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)

Reply via email to