Federico Mariani created CAMEL-24143:
----------------------------------------

             Summary: camel-core - Split & Aggregate EIP review follow-ups 
(medium findings)
                 Key: CAMEL-24143
                 URL: https://issues.apache.org/jira/browse/CAMEL-24143
             Project: Camel
          Issue Type: Bug
          Components: camel-core, eip
    Affects Versions: 4.21.0, 4.22.0
            Reporter: Federico Mariani


Umbrella for the medium findings from a code review of the 
Split/Multicast/Aggregate EIP processors in {{camel-core-processor}} (July 
2026). The high findings are tracked separately: CAMEL-24138 (nested-split 
failure swallow), CAMEL-24139 (watermark data loss on abort), CAMEL-24140 
(UseOriginal + shareUnitOfWork), CAMEL-24141 (recovery/interval task death), 
CAMEL-24142 (lost multicast timeout). Full review document attached.

Items new in CAMEL-23264 (unreleased 4.22.0-SNAPSHOT — can be fixed before 
release):

# *M1 — errorThreshold ratio wrong under parallelProcessing* 
({{Splitter.java:557-563}}): {{ratio = failureCount / (index + 1)}} uses the 
completing item's _original index_ as denominator, not the number of items 
completed so far. With out-of-order parallel completion a 1%-failure run can 
abort at {{errorThreshold(0.5)}} (low-index item failing late), or badly 
under-count. Use a completed-items counter as denominator.
# *M2 — non-failure stop conditions recorded as "failures"* 
({{Splitter.java:543-570}}): with thresholds configured, 
{{shouldContinueOnFailure}} records a {{SplitResult.Failure}} for any 
{{continueProcessing=false}} condition — including exceptions already handled 
by the error handler ({{Failure(index, null)}}), {{rollbackOnly}}, and a 
deliberate {{.stop()}} (routeStop) in the child route, whose semantics are 
silently overridden to "continue".
# *M3 — SplitResult.getSuccessCount() counts never-attempted items as successes 
after an abort* ({{SplitResult.java:63-67}}): {{totalItems}} counts 
prepared/drained items, so after an abort {{totalItems - failureCount}} 
includes unprocessed items; can even go negative combined with CAMEL-24138.
# *M7 — unguarded Integer.parseInt of the stored watermark* 
({{Splitter.java:316-318}}): a non-numeric value under the watermark key (key 
previously used with {{watermarkExpression}}, shared key, corrupted store) 
fails every exchange with a bare {{NumberFormatException}}.

Longstanding:

# *M4 — optimistic-lock async retry can leak the callback* 
({{AggregateProcessor.java:404-410}}): retries scheduled on the 
optimistic-locking executor have no try/catch; an unexpected 
(non-OptimisticLocking) exception from {{doProcess}} on the retry thread 
escapes and the {{AsyncCallback}} is never invoked — the exchange hangs. The 
first attempt is guarded by {{process()}}'s try/catch, the retry path is not.
# *M5 — Statistics.reset() does not reset completedByInterval* 
({{AggregateProcessor.java:207-218}}).
# *M6 — aggregateCompletionCounter NPE on null CamelAggregatedCompletedBy* 
({{AggregateProcessor.java:924-952}}) — also feeds the recovery-task death in 
CAMEL-24141.

Low findings (L1-L6: timeout strategy lookup ignoring per-exchange strategies, 
watermark late-completion NPE, LRU'd error handlers never stopped — a {{Map}} 
is not {{Iterable}} so {{ServiceHelper.stopService}} skips it, 
StringAggregationStrategy delimiter edge, forceCompletionOfAllGroups count, 
errorThreshold first-item-abort docs) are described in the attached review 
document.

_Filed by Claude Code on behalf of Federico Mariani (fmariani)_



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to