shashank created CAMEL-26630:
--------------------------------

             Summary: camel-core - exchange sanitizer: dev-mode checks that 
each exchange's callback runs exactly once and each consumer commit runs once
                 Key: CAMEL-26630
                 URL: https://issues.apache.org/jira/browse/CAMEL-26630
             Project: Camel
          Issue Type: New Feature
          Components: camel-core
            Reporter: shashank
            Assignee: shashank


A dev-mode checker for exchanges, proposed on Zulip and asked for as a design 
proposal, a JIRA and a PR, as was done for camel-chaos (CAMEL-26330).

*Motivation*

Several concurrency bugs found this year broke the contracts of 
{{AsyncProcessor}} and of on completions without failing at the place of the 
bug:
* an exchange completed twice: CAMEL-25095 (camel-jms) and CAMEL-25122 
(camel-sjms), InOut, where a send failure completes an exchange that the 
request timeout or the reply already completed; CAMEL-26446, a throw on the 
first delivery that could continue the exchange twice;
* a processor that throws from {{process(exchange, callback)}} instead of 
calling the callback, so the exchange hangs: CAMEL-26430, CAMEL-26445, 
CAMEL-26461, CAMEL-26464, CAMEL-26601;
* the consumer's commit with a shared unit of work: CAMEL-26569, CAMEL-26576.

User code breaks the same contracts the same way: a custom {{AsyncProcessor}} 
with a timeout of its own that calls the callback from the timeout and again 
from the reply, a custom consumer whose commit runs twice, an 
{{AggregationStrategy}} that throws. The sanitizer checks Camel's code and the 
user's alike, in the tests the user already has.

*Rules*

* R1: the callback of each call of a step's processor is called exactly once. 
Reported: completed twice (logged at the second call, before it continues the 
exchange, with the stack of the first call kept), threw before calling the 
callback, a callback after the processor threw, and, as a warning that 
complements the inflight console, a call still pending.
* R2: each consumer commit (an on completion the consumer adds before routing, 
which can be handed over to a seda copy or shared with shareUnitOfWork; not 
{{UnitOfWork.done}}) runs exactly once, in the unit of work that holds it, and 
is handed over only by the exchange its unit of work was created for.
* R3: an exchange is never used by two threads at the same time, checked 
through the {{AsyncProcessor}} contract ({{doneSync}} equals what {{process}} 
returned) and sampled overlaps in time of the engine's accesses (as KCSAN 
does), with no dependency on a handover API.
* R4: the tasks an executor drops at shutdown are listed.
Pooled exchanges (deprecated in 4.23) are not supported.

*SPI*

Two small listener SPIs in camel-api, {{StepListener}} (the call of a step's 
processor, its return, its throw, each call of its callback) and 
{{OnCompletionListener}} (a unit of work set, an on completion added, handed 
over, taken and run). They only observe, and more than one can be installed, so 
the sanitizer runs together with chaos (which uses the one-per-context 
{{StepHook}}, CAMEL-26338), the debugger, the tracer and JMX. The step listener 
is a wrapper built by the channel around the step's processor only when a 
listener is installed, so with none a step costs nothing more; the on 
completion places check an empty list (measured with JMH).

*Switch*

A {{camel-sanitizer}} module with a {{ContextServicePlugin}}, as camel-chaos: 
on with profile {{dev}} or {{camel.sanitizer.enabled=true}}, never with profile 
{{prod}}. A JUnit extension ({{@CamelSanitizer}}) fails a test on the first 
violation; the test dependency and system properties run an existing suite with 
it in CI; a dev console and {{camel get sanitizer}} show the report.

*Plan*

R1 first, run on the commits before the fixes above to show each one is 
reported at the right step, and on the camel-core suite and the netty, 
netty-http, vertx-http and JMS request/reply suites to show it is quiet on 
main; JMH for the cost; then R2, R3, the console and CLI, and R4 last. Each 
step is its own PR.

Design: design/exchange-sanitizer.adoc (PR to follow).

_Filed with Claude Code on behalf of allthingssecurity._



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

Reply via email to