ammachado opened a new pull request, #28817: URL: https://github.com/apache/camel/pull/28817
# Description [CAMEL-26473](https://issues.apache.org/jira/browse/CAMEL-26473), a tier 2 item of [CAMEL-25132](https://issues.apache.org/jira/browse/CAMEL-25132). `DefaultAsyncProcessorAwaitManager.process` allocated a `CountDownLatch` on every synchronous over asynchronous call, which includes every `ProducerTemplate` send. A temporary counter showed the callback had already fired when the processor returned in 100% of 5000 sends each, on routes with processors, a sub route, split, multicast, redelivery and `seda` with `waitForTaskToComplete=Always`. These routes have no truly asynchronous producer, which is the case that still waits. The callback is now an `AwaitCallback`, which holds the latch in an `AtomicReference`. It is null until the callback fires, which sets a shared `DONE` latch, or until the waiting thread finds it null and sets a new latch with a compare and set. Only then does it wait. Whichever comes second sees the other, so a callback arriving at that moment is not lost. `await` and `countDown` are unchanged and remain public. The blocked exchanges view and forcing a blocked exchange to complete still work on the same latch, which is created before the exchange is listed. ## Measurements Single thread through a `ProducerTemplate` to a route with one processor, no JMX, JDK 25 macOS arm64, 3 million sends, 3 rounds. Not JMH. | | before | after | |---|---|---| | allocated per exchange | 816 B | 768 B | | time per exchange | about 330 ns | about 314 ns | ## Tests 4 new tests in `DefaultAsyncProcessorAwaitManagerProcessTest`: the callback fires before the processor returns, fires twice, fires later from another thread, and races with the processor returning. They pass on the old code too, as the latch is not observable. To check that they can fail, I broke the change in three ways, and each made tests fail: no compare and set on the latch, never waiting, and a callback that does not count down the latch. Verified: 135 tests in `camel-core` selected by name (the await manager, `Async*`, blocked, restart and `SplitAggregate*` tests), 0 failures. The full `camel-core` suite and the component modules were not run locally. # 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. Not run from the root folder: I built the changed core modules through the tests, and `git status` showed only the two changed files afterwards. # 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. 🤖 Generated with [Claude Code](https://claude.com/claude-code) on behalf of Adriano Machado (@ammachado) _This was generated by an AI agent and may contain inaccuracies. Please verify before relying on it._ -- 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]
