[
https://issues.apache.org/jira/browse/CAMEL-24179?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen updated CAMEL-24179:
--------------------------------
Fix Version/s: 4.22.0
> camel-cxf/camel-cxfrs - continuation timeout races with in-flight async
> processing (UoW closed twice, continuation double-resumed)
> ----------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-24179
> URL: https://issues.apache.org/jira/browse/CAMEL-24179
> Project: Camel
> Issue Type: Bug
> Components: camel-cxf
> Reporter: Federico Mariani
> Assignee: Claus Ibsen
> Priority: Major
> Fix For: 4.22.0
>
>
> *Severity:* High
> Affects both the SOAP consumer ({{CxfConsumer}}) and the cxfrs invoker
> ({{CxfRsInvoker}}), which share the same continuation/async structure.
> h3. Problem 1 - timeout mutates and closes an Exchange still being processed
> In {{asyncInvoke}}, the new-request branch calls {{createUoW}},
> {{continuation.suspend(continuationTimeout)}} (default 30000 ms) and then
> {{getAsyncProcessor().process(camelExchange, callback)}}. If the route runs
> longer than the timeout, CXF resumes and the timeout branch runs:
> {code:java}
> camelExchange = (Exchange) continuation.getObject();
> camelExchange.setException(new ExchangeTimedOutException(camelExchange,
> endpoint.getContinuationTimeout()));
> return returnResponse(cxfExchange, camelExchange); // ->
> doneUoW(camelExchange)
> {code}
> This mutates ({{setException}}) and closes the UnitOfWork ({{doneUoW}}) of
> the *same* {{camelExchange}} the worker thread is still processing. Nothing
> synchronizes the two threads on Exchange state
> ({{synchronized(continuation)}} guards only the continuation). With pooled
> exchanges (the modern default), {{doneUoW}} can reset/recycle the Exchange
> while the worker still holds it -> cross-request state corruption under load.
> h3. Problem 2 - unconditional resume after timeout
> The async {{done()}} callback always calls {{continuation.resume()}} with no
> {{isResumed()}}/{{isTimeout()}} guard. After a timeout already produced a
> response and closed the UoW, the late completion resumes again; CXF
> re-invokes, {{returnResponse}}/{{doneUoW}} run a second time ({{uow.done()}}
> is not idempotent), potentially writing a second response onto an
> already-completed servlet response.
> h3. Location
> {{camel-cxf-rest/.../jaxrs/CxfRsInvoker.java}} ~100-133 and
> {{camel-cxf-soap/.../jaxws/CxfConsumer.java}} ~198-230.
> h3. Fix
> Redesign timeout-vs-callback completion so exactly one of {timeout, normal
> completion} owns writing the response and closing the UoW:
> * on timeout, do not mutate/close the in-flight Exchange; mark the
> continuation abandoned and let the async {{done()}} close the UoW once;
> * guard {{done()}} to resume only when the continuation is still pending
> ({{!continuation.isResumed() && !continuation.isTimeout()}}).
> h3. Reproduction
> Set {{continuationTimeout}} low (e.g. 500 ms) and a route with a {{delay}}
> longer than that; assert a single response, a single UoW completion, and no
> state bleed onto a subsequently-pooled exchange. (Timing-sensitive; the two
> problems are one coupled fix.)
> ----
> _Filed by Claude Code (Claude Fable) on behalf of Federico Mariani (GitHub:
> Croway). Findings from an AI-assisted code review of the camel-cxf component
> family; each item was verified against the current source and git history.
> Items marked *[reproducer attached]* include a failing JUnit test that
> demonstrates the defect._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)