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

   # Description
   
   [CAMEL-25014](https://issues.apache.org/jira/browse/CAMEL-25014), a 
regression from CAMEL-24903 (#26799, not released yet)
   
   #26799 made `ThrottlingExceptionRoutePolicy.openCircuit` return at once when 
the circuit is already open, so that `setKeepOpen(true)` can call it safely. 
Two existing callers relied on `openCircuit` acting on an open circuit:
   
   - **Half open handler "not ready":** `calculateState` called `openCircuit` 
to schedule the next half open check. Now no check is scheduled, the consumer 
stays suspended, and no exchange completes to trigger `calculateState` again. 
So the first "not ready" answer suspends the route for good. In a reproduction 
with a file consumer, the handler was called once and 0 of 3 good files were 
processed; with the class from before #26799, it was called twice and all 3 
were processed.
   - **`keepOpen` and a route restart:** the policy's state survives 
`stopRoute`/`startRoute`. After a restart the circuit is still open, so 
`onStart` → `openCircuit` returned before suspending the new consumer, and the 
route consumed 3 of 3 files although `keepOpen` was set.
   
   This change:
   - `openCircuit` keeps the idempotent check under the lock that @davsclaus 
asked for in the #26799 review.
   - The two callers above now use a new `reopenCircuit`. It does what 
`openCircuit` did before #26799, also on an open circuit: suspend the consumer, 
restart the period, and schedule the next half open check.
   - `addHalfOpenTimer` replaces the previous timer under the lock and then 
cancels it. A half open task now cancels only its own timer, not whatever timer 
the field holds. Re-opening therefore never leaves more than one pending check 
or timer thread, and a check that fires while a newer one is being scheduled 
can't cancel it.
   
   Note for subclasses: a subclass that overrides `openCircuit` is no longer 
called on these two paths, which now go through `reopenCircuit` (also 
protected).
   
   Tests: new `ThrottlingExceptionRoutePolicyReopenTest`:
   - `testHalfOpenHandlerNotReadyChecksAgain`: the handler is not ready, and 
the circuit must stay open and be checked again. The test then makes the 
handler ready, and the circuit must close.
   - `testKeepOpenAfterRouteRestart`: the consumer of a stopped and restarted 
`keepOpen` route must be suspended again, and must not consume.
   
   Both fail on main with an Awaitility timeout (`handlerCalls` stays 1, and 
the restarted consumer stays started), and pass with the fix. I ran the new 
test together with `ThrottlingExceptionRoutePolicyOpenViaConfigTest` (the test 
#26799 de-flaked) and `ThrottlingExceptionRoutePolicyKeepOpenOnInitTest` 3 
times: all pass. `ThrottlingException*,*RoutePolicy*,*Throttl*` in camel-core: 
98 tests, 0 failures.
   
   #26799 is labelled `port/camel-4.22.x`. If it is ported, this fix should be 
ported too; could a committer add the same label?
   
   Found with a TLA+ model of the policy (circuit state, half open timer, route 
restart). `NoStuckOpen` and `KeepOpenHolds` fail on main, and hold for the code 
before #26799 and for this change.
   
   # 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 modules, 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]

Reply via email to