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]

Reply via email to