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]

Reply via email to