allthingssecurity opened a new pull request, #29529: URL: https://github.com/apache/camel/pull/29529
# Description [CAMEL-26754](https://issues.apache.org/jira/browse/CAMEL-26754) Since CAMEL-25089 (#26990) `ClusteredRoutePolicy` defers the start of its routes while its initial delay has not elapsed, and only the initial-delay timer marks the delay as elapsed. The timer is armed when the policy learns that the CamelContext has started, from the `CamelContextStartedEvent` or from `onCamelContextFullyStarted`. A policy attached to a CamelContext that has already started gets neither: `addStartupListener` only calls `onCamelContextStarted(context, true)`, which the policy ignores, and the started event was sent earlier. So for a route added after start (with `addRoutes`, a route template or kamelet, a reloaded route) whose policy has an initial delay, every start by the policy is deferred forever: - on a node that is not the leader when the route is added, the route is set to `autoStartup=false` and never starts when the node becomes the leader; when every node added it at runtime it runs nowhere, also after a failover; - on a node that is the leader when the route is added, the route controller starts it, but once the node loses the leadership and takes it again, the route is not started again. `ClusteredRouteController` creates such a policy per route when its `initialDelay` is set. Before #26990 such a route was started when the node became the leader. #26990 is in 4.23.0 (4.22.x is not affected), so this is a 4.23.0 regression and the fix applies as is to `camel-4.23.x`. Change: `onInit` arms the initial delay when the CamelContext is already started, through the same listener method as the started event (guarded by `contextStarted`, so the delay still applies once per policy). It is armed in `onInit` and not in `setCamelContext`, because `ClusteredRouteController` sets the initial delay after the CamelContext: arming it there would happen while the delay is still 0, so no timer would be scheduled, the one-time arming would be used up, and the delay set afterwards would never elapse. Only the timer is scheduled in `onInit` (the guard is `initialDelay > 0`), so the policy lock is not taken on the caller's thread, which may hold the CamelContext route lock. What stays as it was: a route added while the node already is the leader is still started by the route controller right away (as before #26990 and after it). For a policy whose routes are all added after start, the delay counts from when its first route is added, not from the CamelContext start that the `ClusteredRouteController.setInitialDelay` Javadoc mentions (that start is long past for such a route); a policy that already had routes when the CamelContext started keeps its delay from the start. Counting from the CamelContext start for runtime routes could be a follow-up if wanted. Left for a follow-up: a route added while the CamelContext is suspended is also deferred (same root cause, the started notifications), and a policy instance reused across a CamelContext stop and start does not re-create its threads. Tests, in `ClusteredEdgeCasesTest` (in-JVM test cluster view, no sleeps): - `testInitialDelayForRouteAddedAfterStart`: `ClusteredRouteController` with `initialDelay=300ms`, a route added after start, then the node becomes the leader: the route must start, and not before the delay. - `testInitialDelayForRouteAddedAfterStartOnLeader`: the node is already the leader when a route with a policy with an initial delay is added: the route starts, stops when the node loses the leadership, and must start again when the node takes it again. On main both fail (the route stays Stopped). With the fix the camel-core cluster tests pass (51, 0 failures, `org.apache.camel.cluster` and `org.apache.camel.component.file.cluster`), the camel-file cluster tests too (16, 0 failures), and `ClusteredEdgeCasesTest` (6 tests) passes 120/120 over 20 runs in one JVM. Found with Specula (TLA+ model checked against traces of the real 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-26754](https://issues.apache.org/jira/browse/CAMEL-26754). # 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 camel-core cluster tests; 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]
