allthingssecurity opened a new pull request, #27249: URL: https://github.com/apache/camel/pull/27249
# Description [CAMEL-25252](https://issues.apache.org/jira/browse/CAMEL-25252) The timer consumers of the same timer name share one `java.util.Timer`. `TimerComponent` reference counts it: `getTimer` creates it or increments the count, and `removeTimer` decrements the count and cancels the `Timer` at 0. `TimerConsumer` takes a reference only for a delay of 0 or more. A consumer with a negative delay (`delay=-1`, fire as fast as possible, CAMEL-9249) fires from its own executor and never calls `getTimer`. But `doStop` always calls `removeTimer`. So stopping a negative-delay consumer releases a reference it never took. When the reference belongs to another consumer, the shared `Timer` is cancelled while that consumer is running: its route stays Started but never fires again, and nothing is logged. Example: `timer:tick?period=1000` in one route and `timer:tick?delay=-1&repeatCount=1` in another, then the second route is stopped or restarted. This change: `TimerConsumer` remembers whether it took the timer (set where `getTimer` is called, in `doStart` and `onCamelContextStarted`), and `doStop` releases it only then. The flag is set right after `getTimer`, before the task is scheduled, so a reference taken when scheduling fails is still released. This also covers a consumer with a delay of 0 or more that is stopped before the CamelContext has started, which has not taken the timer yet either. Tests: - New `TimerNegativeDelayStopRouteTest` in camel-core, in the style of `TimerMultipleConsumerStopRouteTest`. Route `foo` is `timer:mytimer?period=100`, and route `bar` is `timer:mytimer?delay=-1&repeatCount=1`, started by the test. After `bar` fired, it is stopped once (and in the second test stopped, started and stopped again), and `foo` must keep firing. - Without the change both tests fail: `mock://foo Received message count 0, expected at least 2`. - With the change, the camel-core timer tests pass: 19 classes, 34 tests, 0 failures. camel-timer has no tests of its own. Found with a TLA+ model of the reference count, with consumers that do and do not take the timer, started and stopped in any order. The model cancels a started consumer's timer as soon as a negative-delay consumer is stopped, and holds with the fix. I then reproduced it with the real component. # 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). # 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 and tested the affected module, including the formatter and import-sort plugins. 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]
