allthingssecurity opened a new pull request, #26912: URL: https://github.com/apache/camel/pull/26912
# Description [CAMEL-25037](https://issues.apache.org/jira/browse/CAMEL-25037) **This PR builds on #26911** (`EventDrivenPollingConsumer.receive()` holds the lifecycle lock while it waits). Both change the same lines of `receive()`, so this branch contains that commit too; only the last commit is new here. On its own, the fix is a one-line change of the old loop. `EventDrivenPollingConsumer.receive()` loops while the consumer is running. On an `InterruptedException` it calls `handleInterruptedException`, which since CAMEL-20297 (4.4.0) restores the interrupt status and logs through the interrupted exception handler. The loop then waits on the queue again, and that throws at once because the thread is still interrupted. The thread never leaves `receive()`, even when a message is queued. It uses a full core and logs one WARN per iteration: in a reproducer, 603,114 lines in about 3 seconds. About CAMEL-22390: that ticket reported the same pattern in `SedaConsumer` and was closed with the advice not to interrupt Camel's threads. This case is different. `ConsumerTemplate.receive()` and `PollingConsumer.receive()` run on the **caller's own thread**, the one the application passed in, and the application may legitimately interrupt it. Examples are `Future.cancel(true)` on a task that waits for a message, or `shutdownNow()` of the application's executor. A blocking JDK-style method is expected to return or throw when interrupted, not spin. Camel also interrupts route threads itself during a forced shutdown, and such a thread may be waiting in a `pollEnrich` with the default timeout. This change: on `InterruptedException`, `receive()` keeps the interrupt status (as CAMEL-20297 intended) and returns null instead of waiting again, as `receive(timeout)` already does. It still reports the exception through the interrupted exception handler once. The javadoc of `receive()` now says when it returns null: when the consumer is stopped while waiting, or when the thread is interrupted. Tests: new `EventDrivenPollingConsumerInterruptTest` interrupts a thread waiting in `receive()` and checks, within a 5 second Awaitility bound, that `receive()` returns null, that the interrupt status is kept, and that the handler was called exactly once. Without the main-code change it fails with `ConditionTimeoutException ... was not fulfilled within 5 seconds` (the thread spins until the test stops the consumer). With the change, `*PollEnrich*,*PollingConsumer*,*ConsumerTemplate*,*Enricher*,*ConsumerCache*,*ScheduledPoll*` in camel-core and camel-support pass: 131 tests, 0 failures. Found with the same TLA+ model as #26911. With an interrupt added, `ReceiveEndsAfterInterrupt` is violated by a lasso Interrupt -> wait -> fail -> wait, even with a message queued. I then reproduced it against the real classes. Note: a thread that enters `receive()` with its interrupt flag already set now gets `null` straight away (with the flag kept), instead of spinning. # 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). The commit carries a `Co-Authored-By` trailer. _Claude Code on behalf of allthingssecurity_ 🤖 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]
