[
https://issues.apache.org/jira/browse/CAMEL-25123?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen updated CAMEL-25123:
--------------------------------
Fix Version/s: 4.23.0
> camel-seda - a message that is discarded (discardWhenFull) or not added to a
> full queue loses the on completions of its exchange, so a file consumer never
> commits or rolls back the file
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-25123
> URL: https://issues.apache.org/jira/browse/CAMEL-25123
> Project: Camel
> Issue Type: Bug
> Components: camel-disruptor, camel-seda
> Reporter: shashank
> Priority: Minor
> Fix For: 4.23.0
>
>
> For an InOnly exchange, {{SedaProducer.addToQueue}} creates a copy with
> {{prepareCopy(exchange, true)}}, which hands the on completions of the
> exchange over to the copy: the consumer's commit and rollback (such as the
> file consumer's {{GenericFileOnCompletion}}), {{onCompletion}}
> synchronizations, and the release of a spooled stream cache. The copy is then
> added to the queue. When the copy is not added, it is dropped together with
> those on completions, and they never run:
> * {{discardWhenFull=true}} and the queue is full: the copy is discarded, and
> the exchange completes as a success.
> * the queue is full ({{Queue full}} {{IllegalStateException}}), the
> {{offerTimeout}} elapses ({{Fails to insert element into queue}}), or the
> producer is interrupted: the exchange fails, but its rollback does not run.
> The Disruptor producer has the same problem when the ring buffer is full with
> {{blockWhenFull=false}} (the component default is {{true}}) or the Disruptor
> is not started: {{DisruptorProducer}} hands the on completions over to the
> copy before {{doPublish}} throws.
> Reproduced with a real file consumer,
> {{from("file:in").to("seda:q?size=1&discardWhenFull=true")}} and a slow
> consumer on {{seda:q}}, 4 files:
> {noformat}
> discardWhenFull: 1 consumed, 3 files left in the input directory,
> in-progress repository size 3
> offerTimeout=50: 1 consumed, 3 files left in the input directory,
> in-progress repository size 3
> size=1 (full): 1 consumed, 3 files left in the input directory,
> in-progress repository size 3
> size=10 (control): 4 consumed, 4 files moved to .camel, in-progress
> repository size 0
> {noformat}
> The files of the dropped copies are neither moved nor deleted, and as they
> stay in the file consumer's in-progress repository, they are not picked up
> again (not even after the queue has room again) until the route or the
> application is restarted. With {{offerTimeout}} or a full queue, the exchange
> failed, so the file should have been rolled back and retried.
> With stream caching spooled to disk, the spool file of every discarded copy
> is also left behind until the context stops (a direct route with 4 spooled
> messages to a full queue with {{discardWhenFull}}: 1 of 4 on completions of
> the original exchanges ran, 3 spool files left).
> h3. Proposed fix
> When the copy is not added to the queue (discarded, or adding it failed),
> hand its on completions back to the exchange
> ({{target.getExchangeExtension().handoverCompletions(exchange)}}), so they
> run when the exchange is done, with its outcome:
> * a discarded message completes as before as a success, so its consumer now
> commits it (for example the file is moved to {{.camel}}), as for any message
> whose route completed;
> * a message that could not be added fails as before, so its consumer now
> rolls it back, and can pick it up again.
> The same in {{DisruptorProducer}} when {{doPublish}} fails. This also
> releases the spool file of the copy.
> This differs from CAMEL-24950 (purging the queue), where the copy was
> accepted by the queue and the exchange that sent it had already completed, so
> the dropped copy runs the on completions as a failure itself.
> With the fix: discardWhenFull commits the 3 discarded files; offerTimeout and
> a full queue roll back the files, which are retried and all 4 are consumed;
> no spool file is left behind, and all on completions run. This changes what
> happens to a discarded message, so it needs an upgrade guide note.
> Affected: all 4.x versions (the hand-over to the copy is long-standing).
> Duplicate check (2026-09-29): JIRA "discardWhenFull" (CAMEL-24948, the
> interrupted paths, fixed on main), "offerTimeout" with "seda" (CAMEL-12584,
> the option itself, and CAMEL-24948), "discard" with "onCompletion" and "seda"
> (CAMEL-24950, the purge path, fixed). GitHub pull requests "discardWhenFull":
> nothing on this.
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)