shashank created CAMEL-26882:
--------------------------------

             Summary: camel-core - DefaultProducerCache: an AsyncProducer that 
calls the callback and then throws completes the exchange twice
                 Key: CAMEL-26882
                 URL: https://issues.apache.org/jira/browse/CAMEL-26882
             Project: Camel
          Issue Type: Bug
          Components: camel-core
            Reporter: shashank
            Assignee: shashank


Follow-up of CAMEL-26464, named in the description of its PR and asked for in 
its review; the same on main.

{{DefaultProducerCache.doInAsyncProducer}} (used by {{toD}}, the routing slip, 
{{to}} for a producer that is not optimised, and the async sends of the 
producer template through {{asyncDispatchExchange}}) catches an exception 
thrown by the producer, sets it on the exchange and calls 
{{callback.done(true)}}. When the producer had already called the callback 
before it threw (an {{AsyncProcessor}} that breaks the contract), the exception 
is set on an exchange that has already been continued (maybe on another 
thread), so a send that succeeded fails the exchange (with {{toD}} the steps 
after it do not run), and the callback is called a second time: the error 
handlers ignore that since CAMEL-26445, CAMEL-26461 and CAMEL-26464, but the 
async sends of the producer template release the producer to the pool a second 
time, so a producer of an endpoint that is not a singleton producer can be 
handed to two sends at once. When the producer throws before it calls the 
callback, the producer is not released to the pool (outside the async sends of 
the producer template, where {{asyncDispatchExchange}} calls the callback).

The same happens in {{SendProcessor.sendUsingProducer}} and the sync 
{{DefaultProducerCache.send}}; and with a send hook installed, 
{{SendHelper.HookedSend}} (inside this path) sets the exception and calls 
{{afterSend}} again before the producer cache sees it (left for a follow-up).

*Proposal*
Apply the exactly-once rule of CAMEL-26445, CAMEL-26461 and CAMEL-26464: the 
callback of {{doInAsyncProducer}} completes once (a flag set by whoever 
completes first); a throw after the callback is logged at WARN and not set on 
the exchange; a throw before the callback completes the send as the callback 
would (sent event, release of the producer, callback of the caller). Tests 
where the producer calls the callback and then throws, and where it throws 
before.

_Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to