allthingssecurity opened a new pull request, #28639: URL: https://github.com/apache/camel/pull/28639
# Description [CAMEL-26286](https://issues.apache.org/jira/browse/CAMEL-26286) Every route that consumes from the same `disruptor:` uri shares one `DisruptorEndpoint`. When a route is removed, the core stops and shuts down the endpoint of its consumer (`RouteService.doShutdown`), also when other routes still consume from it. `DisruptorEndpoint.doStop` then calls `DisruptorReference.removeEndpoint`, which shuts down the disruptor and its executor, as this endpoint is the only one of its reference (another endpoint shares the reference only for a uri with the same queue name and other options). So with three routes `from("disruptor:orders?multipleConsumers=true")`, removing one of them (a route template removed, a reload, JMX or controlbus) leaves the two others without messages, and every send fails with `IllegalStateException: Disruptor was not started` (caused by `DisruptorNotStartedException`). A `CamelContext.stop()` afterwards takes about 10 seconds. camel-seda has the same sharing and guards against it in `SedaEndpoint.stop()`/`shutdown()`; the same sce nario on `seda:` keeps delivering to the other two routes. Changes: - `DisruptorEndpoint` overrides `stop()` and `shutdown()`: they do nothing (DEBUG log) while other consumers still use the endpoint, so the disruptor stays up for them. Without consumers, the endpoint stops and shuts down as before. - The consumers of suspended routes count too. A suspended `DisruptorConsumer` leaves the disruptor (as before, so the disruptor stops handing it events), but the endpoint now keeps it in a set of suspended consumers until it resumes or stops. Otherwise suspending two routes and removing a third left the endpoint without consumers, so it was stopped and shut down, and the suspended routes resumed on a disruptor without them: they never received anything again. - Unlike `SedaEndpoint`, producers are not counted. A producer of the uri of a removed route, such as the cached producer of a `ProducerTemplate`, would otherwise keep the old endpoint in the disruptor, and the endpoint that replaces it (the context removes the endpoint from its registry when no other route uses it) could not join it: `DisruptorReference` keeps its endpoints in a set based on `equals`, that is on the uri. The first version of this change counted producers too, and `DisruptorRemoveRouteThenAddAgainTest` failed with it. - disruptor-vm endpoints inherit the change. No option, generated file or upgrade guide change (nothing users relied on changes). - Backport: camel-4.22.x, 4.18.x and 4.14.x have the same `DisruptorEndpoint.doStop` (read, not run). Tests: - New `DisruptorRemoveRouteOfSharedEndpointTest`, MockEndpoint expectations as in the module's other tests: - `removingOneOfSeveralConsumersKeepsTheOthersConsuming` fails on main (3 runs): `IllegalStateException: Disruptor was not started`. - `removingAConsumerRouteKeepsTheSuspendedOnes`: routes a and c suspended, route b removed, a and c resumed, one message: without the suspended consumers it fails after the mock's wait with `mock://c Received message count. Expected: <1> but was: <0>`. - `consumerRouteRemovedAndAddedAgainWhileAProducerRouteUsesTheQueue` (the consumer route reloaded while a producer route stays) passes on main and with the change; it is the control for the path the change leaves as it is. - camel-disruptor: 121 tests, 0 failures. The formatter and import-sort plugins ran. How it was found: a random lifecycle-sequence harness (stop, start, suspend, resume, remove and add of several consumer routes on shared endpoints, with a probe message after every step) over seda, disruptor, timer, scheduler and other consumers shrank the failure to a single remove. Not changed: producers are not counted (above), so removing the last consumer route of a uri still stops its endpoint while a producer of another route sends to it, as on main. Also not changed: the core stops the endpoint of a removed route's consumer even when other routes still use it. Other components whose endpoint `doStop` releases something the other routes of the same uri still use may have the same problem; I can file a follow-up JIRA for the ones I can reproduce. # 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-26286) filed for the change (usually before you start working on it): [CAMEL-26286](https://issues.apache.org/jira/browse/CAMEL-26286). # 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 camel-disruptor and ran its tests, including the formatter and import-sort plugins. No generated file changes. 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]
