allthingssecurity opened a new pull request, #26818: URL: https://github.com/apache/camel/pull/26818
# Description [CAMEL-24959](https://issues.apache.org/jira/browse/CAMEL-24959) An iterator may return `true` from `hasNext()` and then `null` from `next()`. The Splitter skips such null parts (CAMEL-9745, `SplitIteratorNullTest`). With `streaming()` + `parallelProcessing()`, a trailing null part made the split complete at once, while the parts it had already sent were still running. The route continued with only the parts aggregated so far (the original message when none were), and the remaining parts were processed after the route had moved on. `MulticastReactiveTask.run()` found no more pairs and called `doDone(...)` directly. Sequential mode was not affected. CAMEL-21114 fixed the same symptom for transacted routes. This change: when the task finds no more pairs, a new `doDoneNoMorePairs()` treats it like "last pair sent". Under the task lock, it sets `allSent`, aggregates the completed parts that are queued, and completes only when every part sent has been aggregated. Otherwise the last part's `aggregate()` completes it, as it already does when the last part is known. - The lock is needed: a lock-free version could complete as a normal completion while `timeout()` is still calling the strategy. The TLA+ model finds that interleaving. - Aggregating under the lock is needed because `aggregate()` only does `tryLock()`. - The existing poll loop of `aggregate()` moved unchanged into a private `aggregateCompleted()`. - Sequential mode and an empty iterator behave as before. Tests: new `SplitParallelStreamingIteratorNullTest` uses the iterator of `SplitIteratorNullTest`, and the parts wait until the iterator's final `hasNext()` has returned false. Without the fix, `testSplitStreamingParallel` fails with `The split should return the aggregated parts, but returned: ...MyIterator@... ==> expected: <ABC>`. `testSplitStreaming` is the sequential control. `*Multicast*,*Split*,*RecipientList*,*ThreadPoolAbort*`: 579 tests, 0 failures. Full camel-support and camel-core suites with this PR and the other open Multicast, Recipient List and Idempotent Consumer fixes applied together on current `main`: 125 + 7516 tests, 0 failures. Merge note: #CAMEL_24960_PR (CAMEL-24960) changes the catch of the same loop to go through its new `doFailed(e)`. Whichever of the two merges second has a small conflict, and the catch in `aggregateCompleted()` should call `doFailed(e)`. I'll rebase whichever PR is second. I checked the two together, and the full camel-core suite passes. Found with a TLA+ model of the multicast task, then reproduced against the real classes. # Target - [x] I checked that the commit is targeting the correct branch (Camel 4 uses the `main` branch) # Tracking - [x] If this is a large change, bug fix, or code improvement, I checked there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for the change (usually before you start working on it). # Apache Camel coding standards and style - [x] I checked that each commit in the pull request has a meaningful subject line and body. - [ ] I have run `mvn clean install -DskipTests` locally from root folder and I have committed all auto-generated changes. (I built and tested the affected modules, including the formatter and import-sort plugins. I did not run the full root build.) # AI-assisted contributions - [x] If this PR includes AI-generated code, commits have proper co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR description identifies the AI tool used. This PR was prepared with Claude Code (Claude Opus 5.5), on behalf of allthingssecurity. The commits carry a `Co-Authored-By` trailer. 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
