shashank created CAMEL-26883:
--------------------------------

             Summary: camel-core - BacklogDebugger: a resumed exchange can wait 
on the breakpoint of another exchange
                 Key: CAMEL-26883
                 URL: https://issues.apache.org/jira/browse/CAMEL-26883
             Project: Camel
          Issue Type: Bug
          Components: camel-core
            Reporter: shashank
            Assignee: shashank


Found with a TLA+ model of the NodeBreakpoint protocol of 
{{DefaultBacklogDebugger}} (two exchanges at one breakpoint node and the 
debugger client), then reproduced with the real classes.

{{NodeBreakpoint.matchProcess}} registers a {{SuspendedExchange}} with 
{{suspendedBreakpoints.putIfAbsent(nodeId, se)}}, but {{beforeProcess}} works 
by key only: it puts its message with {{suspendedBreakpointMessages.put(nodeId, 
msg)}}, waits on {{suspendedBreakpoints.get(nodeId)}} (not on the 
{{SuspendedExchange}} its own {{matchProcess}} registered), and on a timeout 
removes both entries by key.

# Exchange E1 matched node N; the user resumes N before E1 got to its wait in 
{{beforeProcess}} (E1 first dumps its message there, which can take a while for 
a large body); exchange E2 then matches N and suspends. E1 now finds E2's 
{{SuspendedExchange}} and waits on it, until E2 is resumed or the fallback 
timeout (300 s by default), although it was resumed; and E1's message replaces 
E2's, so the debugger shows E1's message for the exchange that is suspended 
(E2), and the body and header setters act on E2.
# E1 times out at N while the user resumes N and E2 suspends at N: E1's timeout 
removes E2's {{SuspendedExchange}} and message, so E2 waits invisible 
({{getSuspendedBreakpointNodeIds}} is empty, {{resumeBreakpoint(N)}} does 
nothing) until its own timeout.

The single-step breakpoints also remove by key on a timeout, and 
{{singleStepExchangeId}} is an {{ArrayDeque}} changed by the debugger client 
threads and the exchange threads without a lock.

It needs concurrent consumers and a resume (or step, skip, removal, disable) 
while an exchange that just matched a breakpoint still dumps its message; 
{{resumeAll}} from {{camel debug}} does that.

*Proposal*: in {{beforeProcess}} suspend only on the {{SuspendedExchange}} of 
the own exchange (continue when it is gone or belongs to another exchange), 
publish the message only while that one is at the node (in one {{compute}}), 
remove the {{SuspendedExchange}} by value and the message by exchange id (the 
debugger replaces the message object when the body is changed); the same for 
the step breakpoints; a {{ConcurrentLinkedDeque}} for {{singleStepExchangeId}}.

_Filed with Claude Code on behalf of allthingssecurity._



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

Reply via email to