davsclaus opened a new pull request, #26846: URL: https://github.com/apache/camel/pull/26846
_Claude Code on behalf of Claus Ibsen (davsclaus)_ JIRA: https://issues.apache.org/jira/browse/CAMEL-24990 A deep review of the Multicast EIP family (`MulticastProcessor`, `Splitter`, `RecipientList` and `RecipientListProcessor`) found the bugs below. Each fix has a test that fails without it. 1. **A streaming split that stops early read the rest of the input.** When the split finished before its input was consumed (`stopOnException` or a timeout), `MulticastProcessor.doDone` iterated the pairs again to release their exchanges. For a streaming split, that pulled every remaining part from the iterator. Each part got a new exchange and an error handler, and `onPrepare` ran on it, although it was never routed. With 100 parts and a failure at the second one, `onPrepare` ran 100 times instead of 2. On a timeout, the timeout thread iterated the input while the splitter thread could still be reading it, and a very large or endless stream was read to the end. Now `doDone` only releases the pairs when they are a collection. With the default (non-pooled) exchange factory, releasing only updates statistics. 2. **A transacted recipient list shared transaction context data across transactions.** `RecipientListProcessor` kept the `TRANSACTION_CONTEXT_DATA` map in a field. The processor is created once per EIP, so every transacted exchange got the same map. camel-jpa stores each transaction's `EntityManager` in that map, so a later transaction could reuse the `EntityManager` of an earlier one, which is already closed. The map is now created per exchange, as the Multicast and Splitter already do. 3. **A recipient that cannot be resolved leaked the producers of the recipients before it.** Producers are acquired while the recipients are resolved. When a later recipient failed, the exception was thrown before any pair was sent, and the producers already acquired were never released. Prototype endpoints (`cacheSize=-1`) were never stopped. They are now released before the exception is rethrown. ### Related work in this area (not repeated here) - CAMEL-24958 (#26817, merged): release the producers of recipients that were not sent to. That PR covers the pairs that exist when the recipient list is done. Item 3 covers the pairs created before a later recipient fails, which never reach `doDone`. - CAMEL-24960 (#26816, merged): fail a parallel multicast when the thread pool rejects a sub-exchange task. - CAMEL-24959 (#26818, open): a trailing null part in a parallel streaming split. I checked its logic and it looks correct. It doesn't overlap with this PR. ### Not changed (left for follow-up) - **`errorThreshold` aborts on a failed first item.** The failure ratio is computed after each failure, as documented, so a failed first item is already 100%. Whether a minimum number of processed items should apply first is a design question. - **`RecipientList` restart leak.** `RecipientList.doStart` creates a new aggregate executor service each time the route starts, but only shuts it down in `doShutdown`. It has no core threads, so the leak is small. - **Unreachable branch.** `MulticastTransactedTask` still has a branch for parallel processing, which the transacted task never uses. ### Tests - New `SplitterStreamingStopOnExceptionReadAheadTest`, `RecipientListTransactedContextDataTest` and `RecipientListInvalidEndpointReleaseTest`. Each fails without its fix. - All 588 `*Split*`, `*Multicast*` and `*RecipientList*` tests in camel-core pass. - The full `core/camel-core` suite passes. The only failure, `ThrottlingExceptionRoutePolicyOpenViaConfigTest`, is a known flaky test (#26799). 🤖 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]
