fix(spray): guard emitStats against cancelled context#21
Open
wuchulonly wants to merge 2 commits into
Open
Conversation
SprayEngine.execute calls emitStats in a deferred function. When the caller's context times out, the consumer pipeline may already have shut down by the time the defer fires, so the OnStats callback sends to a closed channel and panics. Check ctx.Err() before invoking statsHandler — if the context is already cancelled the callback is a no-op. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TestEmitStats_PanicAfterContextCancel simulates the exact w3 crash: context cancelled → consumer closes channel → emitStats defer fires → statsHandler sends on closed channel → panic. Without the ctx.Err() guard this test fails (panic is triggered). With the guard it passes (callback is skipped). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
send on closed channelpanic whenSprayEngine.execute's deferredemitStatsfires after the consumer pipeline has shut downexecute()callsctx.emitStats()in a defer. When the caller's context times out, the consumer pipeline closes its event channel before the defer fires. TheOnStatscallback then chains back intop.submit()→ send on closed channel → panicctx.Err()inemitStats()before invoking the callback — cancelled context means the consumer is goneObserved in
aiscan hw2026 w3 node —
panic: send on closed channelatpipeline.go:214, goroutine 29767, call chain:execute defer → emitStats → OnStats → emit → p.submitChanges
spray/types.go: addc.ctx.Err() != nilguard inemitStats(1 line change)spray/context_test.go: 4 unit tests covering nil context, nil handler, cancelled context, active contextTest plan
go test ./spray/... -run TestEmitStats— all 4 pass🤖 Generated with Claude Code