allthingssecurity opened a new pull request, #29531: URL: https://github.com/apache/camel/pull/29531
# Description [CAMEL-26756](https://issues.apache.org/jira/browse/CAMEL-26756) When the CamelContext stops, it stops its route controller first, and then the routes, with the shutdown strategy waiting for the in-flight exchanges (45 seconds by default). `ClusteredRouteController.doStop` stopped the cluster service, which stops its views and gives up the leadership (the file lock is released, a lease is no longer renewed). So when the leader was stopped gracefully (rolling restart, redeploy) while it still had in-flight exchanges, another node could become the leader (on its next lock attempt, or once the lease expired) and start the clustered routes while this node still processed them, and its consumers could still take messages until they were stopped: two nodes consuming at the same time, which is what the clustered route controller is used to avoid. `master:` routes using the same cluster service had the same problem, as their views were stopped with the service. Change: - When the CamelContext is stopping, `doStop` no longer stops the cluster service. An event notifier, registered by the controller when it starts, stops it on `CamelContextRoutesStoppedEvent`, once the shutdown strategy has stopped the routes (and their policies have released their views). The notifier ignores the exchange, route, service and step events, so it does not turn on exchange event notification. - A controller stopped on its own, while the CamelContext is not stopping, still stops the cluster service right away, as before. Upgrade guide (4.24): a node being stopped can keep (or still take) the leadership until its routes have finished their in-flight exchanges, so a graceful stop can hand over the leadership later than before, by up to the shutdown timeout (45 seconds by default); lowering the shutdown timeout is the way back. The Javadoc of `setClusterService` says when the controller stops the service. The end state is the same as before: a cluster service set with `setClusterService` (which the controller starts) is stopped by the controller, and a service of the CamelContext is stopped (it is also stopped later by the CamelContext itself). Only the moment changes. Tests, in the new `ClusteredRouteControllerStopTest` (in-JVM test cluster service, latches, no sleeps): a clustered route whose processor waits on a latch takes an exchange, then the CamelContext is stopped on another thread. Once the route controller has stopped, the cluster service must still be started and the view still the leader; after the exchange is released and the CamelContext has stopped, the service must be stopped. Two variants: the cluster service is a CamelContext service, or it is only set on the controller. Two more tests keep the other paths: a route controller stopped on its own while the CamelContext runs stops the service right away, and a service set on the controller is started and stopped again on each CamelContext start and stop, with the listener registered once. Left as it is: a custom `EventFactory` that creates no `CamelContextRoutesStoppedEvent`, or a custom `ManagementStrategy` that does not start notifiers added later, would leave a service set with `setClusterService` running until the JVM exits. On main 3 of the 4 tests fail: the two in-flight tests (the service is already stopped while the exchange is in flight) and the restart test (there is no listener); the test of a route controller stopped on its own passes on main too, as that behaviour does not change. With the fix: camel-core cluster tests 53/0 (`org.apache.camel.cluster`, `org.apache.camel.component.file.cluster`), camel-file cluster tests 16/0, camel-master 32/0, `ManagedClusterServiceTest` 1/0, and the new test class (4 tests) 80/80 over 20 runs in one JVM. Found in a code review of the cluster code and confirmed with the tests above. # 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): [CAMEL-26756](https://issues.apache.org/jira/browse/CAMEL-26756). # 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 the core modules with the formatter and import-sort plugins and ran the cluster tests of camel-core, camel-master and camel-management; 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]
