[
https://issues.apache.org/jira/browse/CAMEL-24926?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen resolved CAMEL-24926.
---------------------------------
Fix Version/s: 4.23.0
Resolution: Fixed
The fix is merged on main, so it is in Camel 4.23.0:
* 56c40ea0035b CAMEL-24926: camel-core - Concurrent requests throttler should
not let more exchanges in than allowed after its state is
Resolving, as the ticket was not updated when the PR was merged.
_Claude Code on behalf of Claus Ibsen_
> throttle(n).concurrentRequestsMode() lets more than n exchanges in when one
> of them takes longer than 10 seconds
> ----------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-24926
> URL: https://issues.apache.org/jira/browse/CAMEL-24926
> Project: Camel
> Issue Type: Bug
> Components: camel-core
> Reporter: shashank
> Priority: Minor
> Fix For: 4.23.0
>
>
> With {{throttle(1).concurrentRequestsMode()}}, two exchanges can be inside
> the throttled part of the route at the same time:
> # Exchange X passes the throttle and completes. Returning its permit
> schedules a cleanup of the throttler state 10 seconds later.
> # Exchange A takes the permit and runs for 15 seconds.
> # The cleanup runs while A is still being processed and removes the state
> (the semaphore).
> # Exchange B arrives. There is no state for the key anymore, so a new one
> with all permits is created, and B passes the throttle while A still holds
> its permit.
> Observed with a route whose processor sleeps for slow messages:
> {noformat}
> t= 0.25s enter X (inside: 1)
> t= 0.26s leave X
> t= 0.77s enter A (inside: 1)
> t=11.28s enter B (inside: 2)
> t=12.28s leave B
> t=15.78s leave A
> max concurrent exchanges inside throttle(1).concurrentRequestsMode() = 2
> (expected 1)
> {noformat}
> Any exchange that holds a permit for longer than 10 seconds after the
> previous permit was returned breaks the limit, which is a typical case for
> this mode (a slow backend that only accepts n connections).
> Cause: {{ConcurrentRequestsThrottler.ThrottlingState.release()}} schedules
> {{clean()}} after {{CLEAN_PERIOD}} (10 s), and {{clean()}} calls
> {{states.remove(key)}} without checking whether a permit was taken in the
> meantime. Taking a permit does not cancel the scheduled cleanup.
> Proposed fix: only remove the state in {{clean()}} when all permits are
> available and nobody is waiting for one. To close the remaining window where
> an exchange has looked up the state just before it was removed, mark the
> state as removed (under the state lock), and have an exchange that took a
> permit from a removed state give it back and take one from the current state
> instead.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)