[
https://issues.apache.org/jira/browse/CAMEL-24800?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Work on CAMEL-24800 started by Federico Mariani.
------------------------------------------------
> camel-core - pooled exchange copies share the parent's clock, so Splitter
> children are returned to the pool without reset (properties/variables leak
> between messages)
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-24800
> URL: https://issues.apache.org/jira/browse/CAMEL-24800
> Project: Camel
> Issue Type: Bug
> Components: camel-core
> Affects Versions: 4.22.0
> Reporter: Federico Mariani
> Assignee: Federico Mariani
> Priority: Major
> Attachments: PooledExchangeSplitLeakTest.java
>
>
> When exchange pooling is enabled ({{PooledExchangeFactory}} +
> {{PooledProcessorExchangeFactory}}), the Splitter's child exchanges are
> returned to the pool *without being reset*, so exchange properties and
> exchange-scoped variables set while processing one message leak into the
> children of the next message that goes through the same split.
> *Cause*: {{DefaultPooledExchange(Exchange parent)}} reuses the parent's
> {{ResetableClock}} instance when the parent already has one (since
> CAMEL-20225, 4.4):
> {code:java}
> if (parentClock instanceof ResetableClock rs) {
> this.clock = rs; // shared with the parent
> } else {
> this.clock = new ResetableClock(parent.getClock());
> }
> {code}
> The Splitter creates every child via {{createCorrelatedCopy}} from its
> (pooled) working copy, so parent and child share one clock. On completion the
> working copy is released first: its {{done()}} calls {{clock.unset()}}
> (created = 0). The child's {{done()}} then hits the guard {{if
> (clock.getCreated() > 0)}} and skips the whole reset (properties, variables,
> extension flags, message), and the dirty exchange is offered back to the pool.
> *Reproducer* (attached as a unit test): pooled factories,
> {{from("direct:start").split(body()).process(...).to("mock:split")}}; the
> child of the first message sets an exchange property and a variable; the
> child of the second message must not see them, but sees both
> ({{leakProp=from-first}}, {{leak=from-first}}). Headers do not leak because
> reuse overwrites the message.
> *Fix*: give every pooled copy its own clock ({{new
> ResetableClock(parentClock)}} unconditionally). Verified: the reproducer
> passes with that change. Not a regression of a specific release; present
> since 4.4.
> _Claude Code on behalf of Federico Mariani_
--
This message was sent by Atlassian Jira
(v8.20.10#820010)