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

   # Description
   
   [CAMEL-26472](https://issues.apache.org/jira/browse/CAMEL-26472), a tier 2 
item of [CAMEL-25132](https://issues.apache.org/jira/browse/CAMEL-25132).
   
   Both throttler modes scheduled a new clean of the throttling state and 
cancelled the previous one for every exchange, which goes through the scheduled 
executor queue lock.
   
   Changes:
   
   1. **`AbstractThrottler.scheduleClean`** keeps the pending clean while at 
least a fifth of the clean period is left, and otherwise reschedules as before. 
A clean that already ran has no delay left, so it is rescheduled too.
   2. **The clean task is one `Runnable` per state**, not a new method 
reference per exchange.
   3. **`ThrottlePermit.compareTo`** compares the scheduled times, instead of 
reading the clock twice.
   
   ## Why the clean cannot run too early
   
   `TotalRequestsThrottler` removes a state whose permits are all returned, 
even if they are still delayed, so a clean within the delay of a permit would 
hand out a fresh set of permits (see CAMEL-25300). The clean period there is 10 
time periods, so a pending clean stays only if it is at least 2 periods away, 
which is after the 1 period delay of the permit just returned. The check uses 
the current period, so raising it at runtime reschedules on the next exchange.
   
   `ConcurrentRequestsThrottler` checks in `clean()` that no permit is taken. A 
state still in use when the clean runs is rescheduled on the next release.
   
   **Behavior change:** the clean of a state now runs 8 to 10 periods after the 
last permit was returned in total requests mode, and 8 to 10 seconds in 
concurrent mode, instead of exactly 10. This only affects when an idle state is 
removed, for example how soon `getCurrentMaximumRequests` goes back to 0. There 
is no upgrade guide entry, as this timing was not documented.
   
   ## Measurements
   
   A temporary `ProducerTemplate` harness, not JMH, on JDK 25 macOS arm64, no 
JMX. "Before" forces a reschedule on every exchange, on the same build, so it 
has the new `compareTo` and shared `Runnable`. The route is short, so this 
shows the throttler cost at its largest. macOS multi-thread numbers can mislead 
(see the umbrella ticket), so these are indicative only, and the 4 thread 
concurrent result was noisy.
   
   | mode | threads | before, ops/s | after, ops/s |
   |---|---|---|---|
   | total requests | 1 | about 1.6M | about 1.7M |
   | total requests | 4 | about 705k | about 870k |
   | concurrent requests | 1 | about 1.9M | about 2.25M |
   | concurrent requests | 4 | about 1.2M | 2.0M to 4.2M |
   
   Allocation is about 96 B less per exchange in both modes.
   
   ## Tests
   
   5 new tests in the two `*RequestsThrottlerCleanTest` classes. 
`testCleanStaysScheduledWhileFarFromFiring` failed in both classes on the old 
code (2 schedules instead of 1). The others pin the safety rule: a clean close 
to firing is rescheduled, and so is one that a raised time period brings close. 
Each failed when I weakened the check: the threshold at 1 period, at a tenth of 
a period, and a fixed threshold that ignores the current period.
   
   `ThrottlePermit.compareTo` has no new test. It is covered through the 
`DelayQueue` by the existing throttler tests.
   
   Verified: 93 tests matching `*Throttl*` in `camel-core` and 12 in 
`camel-management`, 0 failures. The full `camel-core` suite and the 
deterministic simulation tests were not run locally. `DstTask.getDelay` reads 
the virtual clock, so `scheduleClean` should work there, but that was read from 
the code, not run.
   
   # 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.
   
   Not run from the root folder: I ran `mvn install -Dquickly` on the changed 
core modules, and `git status` showed no generated changes afterwards.
   
   # 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.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code) on behalf of 
Adriano Machado (@ammachado)
   
   _This was generated by an AI agent and may contain inaccuracies. Please 
verify before relying on it._


-- 
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