shashank created CAMEL-26885:
--------------------------------
Summary: camel-core - Supervising route controller: the routes and
nonSupervisedRoutes sets are not thread-safe
Key: CAMEL-26885
URL: https://issues.apache.org/jira/browse/CAMEL-26885
Project: Camel
Issue Type: Bug
Components: camel-core
Reporter: shashank
Assignee: shashank
Follow-up of the supervising route controller deadlock fix (CAMEL-26448).
{{DefaultSupervisingRouteController}} keeps the routes it controls in a
{{TreeSet}} ({{routes}}) and the routes it does not supervise in a {{HashSet}}
({{nonSupervisedRoutes}}). Both are changed and read from several threads
without one lock:
* {{ManagedRoutePolicy.onInit}} adds to both without a lock (a route added at
runtime, Kamelets, route templates); {{onRemove}} removes under the policy's
own {{BaseService}} lock, not the controller lock;
* {{startRoute}} / {{stopRoute}} / {{suspendRoute}} / {{resumeRoute}} and
{{getControlledRoutes()}} stream {{routes}} without a lock (JMX, the control
bus, the developer console, a route reload);
* {{getNonControlledRouteIds()}} hands out a live (unmodifiable) view of the
{{HashSet}}, so a caller that iterates it while a route is added gets a
{{ConcurrentModificationException}}.
A route added or removed while another thread looks up a route can fail with a
{{ConcurrentModificationException}} (or {{IllegalStateException: Accept
exceeded fixed size}} from {{toList()}}), or miss a route that is there, so it
is started without the supervision.
Also, an exhausted restart task can still put a route that is being removed
into {{exhausted}}: CAMEL-26448 narrowed this (the callback checks under the
controller lock that the task is still the restart task of the route), but
{{onRemove}} releases the route under the policy lock, so it can run between
that check and the put; the removed route then stays exhausted (and unhealthy).
This part is left for a follow-up.
*Proposal*: concurrent collections ({{ConcurrentSkipListSet}} with the same
ordering, {{ConcurrentHashMap.newKeySet()}}) rather than more locking (taking
the controller lock in {{onInit}} runs under the route lock of the
CamelContext, see CAMEL-26448).
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)