allthingssecurity opened a new pull request, #29787:
URL: https://github.com/apache/camel/pull/29787

   # Description
   
   [CAMEL-26883](https://issues.apache.org/jira/browse/CAMEL-26883)
   
   `DefaultBacklogDebugger.NodeBreakpoint.matchProcess` registers the 
`SuspendedExchange` of an exchange at a node with 
`suspendedBreakpoints.putIfAbsent(nodeId, se)`, but `beforeProcess` then works 
by key only: it puts the message of its exchange 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. Found 
with a TLA+ model of this protocol (two exchanges at one breakpoint node and 
the debugger client), then reproduced with the real classes. It needs 
concurrent consumers and a resume (or a step, a skip over, a removal or a 
disable of the breakpoint) at the moment an exchange has just matched a 
breakpoint and still dumps its message; `resumeAll` from `camel debug` resumes 
such an exchange, which the user has not seen yet:
   
   - Exchange E1 matches the breakpoint at node N; the user resumes N before E1 
reached its wait (E1 first dumps its message, which takes a while for a large 
body); exchange E2 then suspends at N. E1 finds E2's `SuspendedExchange` and 
waits on it, until E2 is resumed or the fallback timeout (300 seconds by 
default), although E1 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 of the debugger 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.
   
   Change, in `DefaultBacklogDebugger`:
   - `NodeBreakpoint.beforeProcess` suspends only on the `SuspendedExchange` of 
its own exchange: when it is gone (resumed meanwhile) or belongs to another 
exchange, the exchange continues. Its message is published only while its 
`SuspendedExchange` is the one at the node, in one `compute` with that check (a 
resume and another exchange can come in between). After the wait it removes its 
message by exchange id (the debugger replaces the message object when the body 
or a header is changed at the breakpoint), and on a timeout its 
`SuspendedExchange` by value;
   - the single-step breakpoints remove their entries the same way on a timeout;
   - `singleStepExchangeId`, changed by the threads of the debugger client and 
of the exchanges, is a `ConcurrentLinkedDeque` (was an `ArrayDeque`; by 
reading, not covered by a test).
   
   It is still one suspended exchange per node (`putIfAbsent` in 
`matchProcess`), and a timeout still removes the entries of its own exchange, 
as CAMEL-21747 added. A statement-level model of the committed code holds for 
two exchanges, the resume and the timeout (it does not cover the step 
breakpoints or the message refresh; the second test covers the refresh). With 
one exchange at a node at a time, the only difference: when the breakpoint is 
resumed (or the debugger disabled) while the exchange still dumps its message, 
the exchange no longer leaves its message behind at the node.
   
   Tests, new `BacklogDebuggerResumedBeforeSuspendTest` (camel-management, next 
to `BacklogDebuggerEdgeCasesTest`):
   - `testResumedBeforeTheExchangeSuspended`: E1 matches the breakpoint and is 
held while the debugger dumps its message (a body whose conversion to text 
waits on a latch, only at the breakpoint); the test resumes the breakpoint, 
sends E2, which suspends there, then releases E1. E1 must reach the end of the 
route without another resume, and the debugger must still show E2 (its exchange 
id and body) as the suspended exchange; then E2 is resumed. Without the change 
E1 waits on E2's latch (the mock times out);
   - `testTimeoutAfterTheBodyWasChangedLeavesNoMessage`: the body is changed at 
the breakpoint, the breakpoint times out (fallback timeout 2 seconds), and no 
message or suspended exchange is left at the node. It passes on main too; it is 
the only test of the changed timeout path, and it guards the removal by 
exchange id (a removal by message object would leave the replaced message 
behind).
   
   The timeout scenario with two exchanges is covered by the model, not by a 
test. With it the camel-core tests (9181 run, 0 failures, 45 skipped) and the 
camel-management tests (603 run, 0 failures, 1 skipped) pass, and the debugger 
tests again on the final commit (`BacklogDebugger*Test` and `*Debugger*Test`, 
24 run, 0 failures).
   
   No documentation or upgrade guide change.
   
   # Target
   
   - [x] I checked that the commit is targeting the correct branch (Camel 4 
uses the `main` branch)
   
   # Tracking
   - [x] If this is a large change, bug fix, or code improvement, I checked 
there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for 
the change (usually before you start working on it): 
[CAMEL-26883](https://issues.apache.org/jira/browse/CAMEL-26883).
   
   # Apache Camel coding standards and style
   
   - [x] I checked that each commit in the pull request has a meaningful 
subject line and body.
   - [ ] I have run `mvn clean install -DskipTests` locally from root folder 
and I have committed all auto-generated changes.
     (I built the core modules and camel-management with the formatter and 
import-sort plugins and ran the tests named above. I did not run the full root 
build.)
   
   # AI-assisted contributions
   
   - [x] If this PR includes AI-generated code, commits have proper 
co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR 
description identifies the AI tool used.
     This PR was prepared with Claude Code (Claude Opus 5.5). The commit 
carries a `Co-Authored-By` trailer.
   
   _Claude Code on behalf of allthingssecurity_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to