A deliberate stop of the realtime channel could be reported as a failure of the run.
What was wrong
The reader could be overtaken by the cancellation of the caller: the shutdown aborted the socket, the reader then used it and failed with "disposed", and the run ended with that failure instead of ending normally.
The platform socket also aborts itself as soon as the token of a call in flight is cancelled, before the channel has looked at its loops, so a loop could fail on the socket even before the shutdown began.
What changes
The shutdown records whether the caller had cancelled and which loop had already failed.
A failure is taken to be the stop only when it is one of the two ways an ended socket refuses a call (disposed, or invalid state) and the loop is not known to have failed first.
Every other failure is still reported whenever it arrives, also beside a cancellation: an input or output error, and a connection the server dropped (closed prematurely).
A send still waiting for its acknowledgement is not given, as its cause, a refusal the run took to be the stop.
Verification
Head 3053200 on release/2.0 at 6f0237d.
build/Verify.ps1 passed on that head: 773 Core, 1,117 Windows runtime and command line, 352 presentation tests, none failed; Core 100% of 2,141 lines; coverage gate passed.
The realtime channel, traffic transport and scripted socket tests were run 12 times in a row with no failure.
Review (independent reviewer, three passes)
cc9bb0f (replayed here as 2570e17, git range-diff identical): two should-fix, nits.
3c47c15: Verdict on 3c47c15: 0 blockers, 2 should-fix, 3 nits. Both should-fix were weak tests.
3053200, the head merged: Verdict on 3053200: 0 blockers, 0 should-fix, 2 nits.
Left open, to be recorded in the audit
No test pins the cause given to a waiting send (the reviewer has a test body for it).
The scripted socket does not model the platform socket's own abort on a cancelled token, so the premise of one test is stated only in a comment.
A deliberate stop of the realtime channel could be reported as a failure of the run.
**What was wrong**
- The reader could be overtaken by the cancellation of the caller: the shutdown aborted the socket, the reader then used it and failed with "disposed", and the run ended with that failure instead of ending normally.
- The platform socket also aborts itself as soon as the token of a call in flight is cancelled, before the channel has looked at its loops, so a loop could fail on the socket even before the shutdown began.
**What changes**
- The shutdown records whether the caller had cancelled and which loop had already failed.
- A failure is taken to be the stop only when it is one of the two ways an ended socket refuses a call (disposed, or invalid state) and the loop is not known to have failed first.
- Every other failure is still reported whenever it arrives, also beside a cancellation: an input or output error, and a connection the server dropped (closed prematurely).
- A send still waiting for its acknowledgement is not given, as its cause, a refusal the run took to be the stop.
**Verification**
- Head `3053200` on `release/2.0` at `6f0237d`.
- `build/Verify.ps1` passed on that head: 773 Core, 1,117 Windows runtime and command line, 352 presentation tests, none failed; Core 100% of 2,141 lines; coverage gate passed.
- The realtime channel, traffic transport and scripted socket tests were run 12 times in a row with no failure.
**Review (independent reviewer, three passes)**
- `cc9bb0f` (replayed here as `2570e17`, `git range-diff` identical): two should-fix, nits.
- `3c47c15`: `Verdict on 3c47c15: 0 blockers, 2 should-fix, 3 nits.` Both should-fix were weak tests.
- `3053200`, the head merged: `Verdict on 3053200: 0 blockers, 0 should-fix, 2 nits.`
**Left open, to be recorded in the audit**
- No test pins the cause given to a waiting send (the reviewer has a test body for it).
- The scripted socket does not model the platform socket's own abort on a cancelled token, so the premise of one test is stated only in a comment.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
RunAsync returns when its caller cancels and throws when the channel ended
by itself. Its shutdown aborts the socket, and a loop that has checked the
token and is about to use the socket at that moment fails on the aborted
socket instead of seeing the cancellation. The run then threw that failure
although nothing had failed, so a deliberate stop could be reported as a
dropped connection. A full verification run hit it once in
ErrorFailsTheWaitingSendWithTheMatchingStatus.
A loop that had not failed when the shutdown began, and then fails the way
an aborted socket fails (disposed, or a socket error), is now the shutdown
itself. Any other failure is still reported whenever it arrives, and a
loop that had already failed before the shutdown is reported whatever it
failed with.
The scripted socket gains a hook at the start of a receive, and a new test
holds the reader there until the socket is aborted. It fails on the old
code every time.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
Review round on the channel shutdown race.
The platform socket aborts itself as soon as the token of a call in
flight is cancelled, before the channel's own shutdown has looked at the
loops. A loop that then used the socket failed before the snapshot and
was reported as a failure of the run although the caller had asked for
the stop. The snapshot now records whether the caller had cancelled, and
a loop counts as failed first only when it had not.
The failure that is taken to be the stop is narrowed to the two ways an
ended socket refuses a call: disposed, or in an invalid state. A
connection the server dropped (closed prematurely) and any other error
are reported whenever they arrive, also beside a cancellation.
Tests pin the rule by kind of failure, and the case where the refusal
arrives before the shutdown begins.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
Second review round on the channel shutdown race.
The test for a refusal that arrives before the shutdown begins released
the reader as soon as the writer was about to fail, so the reader could
end first and the test passed about half the time with the fix removed.
The reader is now held until the shutdown aborts the socket, which only
follows a loop ending.
Nothing pinned the reads of which loop had failed first once the caller's
cancellation was taken into account. A new test has no cancellation at
all: the callback gives up while the writer is in a send, and the
writer's late refusal must not replace the cancellation.
A send still waiting for its acknowledgement is no longer given, as its
cause, a refusal the run itself took to be the caller's stop.
The traffic test on a real socket no longer tolerates a socket failure
when its run is stopped; a deliberate stop ends the run normally.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
A deliberate stop of the realtime channel could be reported as a failure of the run.
What was wrong
What changes
Verification
3053200onrelease/2.0at6f0237d.build/Verify.ps1passed on that head: 773 Core, 1,117 Windows runtime and command line, 352 presentation tests, none failed; Core 100% of 2,141 lines; coverage gate passed.Review (independent reviewer, three passes)
cc9bb0f(replayed here as2570e17,git range-diffidentical): two should-fix, nits.3c47c15:Verdict on 3c47c15: 0 blockers, 2 should-fix, 3 nits.Both should-fix were weak tests.3053200, the head merged:Verdict on 3053200: 0 blockers, 0 should-fix, 2 nits.Left open, to be recorded in the audit
🤖 Generated with Claude Code