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)