allthingssecurity opened a new pull request, #28757:
URL: https://github.com/apache/camel/pull/28757

   # Description
   
   [CAMEL-26334](https://issues.apache.org/jira/browse/CAMEL-26334)
   
   `OnceConsumer` created a `java.util.Timer` in its constructor (`new 
Timer(endpoint.getName())`, a non-daemon thread named after the endpoint) and 
never cancelled it; `doStop` only cancelled the `TimerTask`. The thread stayed 
alive after the route was stopped and after the CamelContext was stopped, and 
after the route was removed it ended only when the consumer was garbage 
collected (the cleaner of `java.util.Timer`). So every once route that was 
created, or reloaded in dev mode, kept a non-daemon thread until then. A once 
route that was stopped and started again did not start: `doStart` scheduled the 
cancelled `TimerTask` again and failed with `IllegalStateException: Task 
already scheduled or cancelled`. A CamelContext with a once route that was 
stopped and started again failed to start the same way, and so did the resume 
of a suspended once route (the consumer cannot be suspended, so the route 
controller stops and starts it).
   
   Changes (`OnceConsumer`):
   - The consumer fires on a single thread scheduled executor that `doStart` 
creates through the `ExecutorServiceManager` 
(`newSingleThreadScheduledExecutor(this, endpoint.getName())`, so the thread is 
named `Camel (<context>) thread #N - <name>` and the pool is managed like the 
other Camel pools).
   - `doStop` cancels the pending fire with `cancel(false)`, so a fire that is 
routing an exchange is not interrupted (as with `TimerTask.cancel()`), and 
shuts the executor down.
   - Each start schedules a new fire, so a restarted route fires again, which 
is what `doStop` resetting `scheduled` meant.
   - `scheduleTask(TimerTask, Timer)` is replaced by `scheduleTask()`; it does 
nothing before the consumer started (no executor yet).
   - This also removes the `TimerTask` from camel-once, which CAMEL-22957 
listed for virtual thread support.
   
   Docs: upgrade guide 4.24, a `camel-once` entry (the thread name, the 
restart, the protected method).
   
   Tests: new `OnceConsumerLifecycleTest` (5 tests, latches and `Thread.join`, 
no sleeps; JUnit assertions, the module has no AssertJ dependency):
   - `theThreadEndsWhenTheCamelContextStops`
   - `theThreadEndsWhenTheRouteIsRemovedBeforeItFired` (`delay=3600000`)
   - `noThreadIsLeftPerRouteThatWasAddedAndRemoved` (20 routes added, fired, 
stopped and removed)
   - `aRouteThatIsStartedAgainFiresAgain`
   - `aRouteFiresAgainWhenTheCamelContextIsStartedAgain`
   
   All 5 fail on main (the first three list the non-daemon threads still alive 
after 10 s, the last two with the `IllegalStateException`) and pass with the 
fix. camel-once: 16 tests, 0 failures. Also checked with a throwaway test: a 
suspended and resumed once route fires again (on main the resume fails with the 
same exception), and a route with `autoStartup=false` fires only when it is 
started, as on main. The formatter and import-sort plugins ran on the final 
files (a second run: 0 formatted, already sorted).
   
   Backport: the same code is on 4.18.x and 4.22.x (since 4.17.0). The thread 
name changes, so it can stay on main, or go back with the guide note.
   
   # 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-26334) 
filed for the change (usually before you start working on it): 
[CAMEL-26334](https://issues.apache.org/jira/browse/CAMEL-26334).
   
   # 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-once with the core modules and ran its tests, including the 
formatter and import-sort plugins. No option or 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