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]
