shashank created CAMEL-24926:
--------------------------------
Summary: 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
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)