shashank created CAMEL-24923:
--------------------------------

             Summary: Weighted load balancer accepts negative, all-zero or 
overflowing distribution ratios, and the caller then hangs
                 Key: CAMEL-24923
                 URL: https://issues.apache.org/jira/browse/CAMEL-24923
             Project: Camel
          Issue Type: Bug
          Components: camel-core
            Reporter: shashank


{{loadBalance().weighted(...)}} only checks that the number of ratios matches 
the number of endpoints. The values themselves are not checked, and some values 
make every exchange hang instead of failing:

* {{weighted(true, "0,0")}} (round robin): the selection loop in 
{{WeightedRoundRobinLoadBalancer.chooseProcessor}} never finds a processor with 
a positive weight and spins forever, at 100% CPU, while holding the load 
balancer lock.
* {{weighted(true, "1,-1")}}: the first message works, the second one spins the 
same way.
* {{weighted(false, "0,0")}} (random): {{ThreadLocalRandom.nextInt(0)}} throws 
{{IllegalArgumentException: bound must be positive}} from {{process()}}. The 
callback is never called, so a synchronous caller (for example 
{{ProducerTemplate.send}}) waits forever in 
{{DefaultAsyncProcessorAwaitManager.await}}. Nothing is logged and no exception 
reaches the exchange.
* {{weighted(false, "2147483647,1")}}: the ratio sum is computed with {{int}} 
and wraps to {{-2147483648}}, with the same result as above.
* {{weighted(true, "2147483647,2147483647,3")}}: the sum wraps to {{1}}, and 
every message goes to the first endpoint.

In all cases the route starts without any error.

Cause: {{WeightedLoadBalancer}} does not validate the ratio values, and 
{{QueueLoadBalancer.process}} does not catch an exception thrown by 
{{chooseProcessor}}, so it escapes the asynchronous processing contract (the 
exchange is not completed).

Proposed fix: validate the ratios in {{WeightedLoadBalancer.doStart}}, next to 
the existing ratio count check: each ratio must be 0 or positive, at least one 
must be positive, and the sum must fit in an {{int}}. A ratio of 0 for some 
endpoints keeps working (that endpoint gets no messages). In addition, 
{{QueueLoadBalancer.process}} should set an exception thrown by 
{{chooseProcessor}} on the exchange and call the callback. This also covers a 
sticky load balancer whose correlation expression throws.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to