Repository navigation
fix(server): UDP readers exit when the server is closed - #57
Merged
Merged
Conversation
readLoopBatches recognised a closed socket by comparing the inner
error's text to "use of closed network connection". On the Linux
recvmmsg path the error is wrapped twice ("read udp ...: raw-read udp4
...: use of closed network connection"), so the comparison never
matched: after Close every reader (2 x NumCPU of them) logged at Debug
and retried the closed socket forever, a hot loop per core for the
rest of the process.
Match net.ErrClosed with errors.Is, and also end the loop on any read
error once Close has begun (s.done).
TestCloseStopsReaders starts a server, closes it and waits for the
goroutine count to return to its baseline. On Linux (10 CPUs, 20
readers) it fails without this change ("base=2 running=36 now=22")
and passes with it ("after Close=2").
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
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.
Problem
readLoopBatchesdetected a closed socket by comparing the inner error's text to"use of closed network connection". On Linux's recvmmsg path the error is wrapped twice:so the comparison never matched. After
Close, each of the2 x NumCPUreaders logged at Debug and retried its closed socket forever, which is a hot loop per core for the rest of the process.errors.Is(err, net.ErrClosed)istruefor that error.Measured on v0.2.9 (Linux arm64 container, 10 CPUs): 2 goroutines before
ListenAndServe, 36 while running, 22 two seconds afterClose.This also affects web4's
TestDaemonShutdownStopsGoroutines, which starts an in-process beacon. On a runner with 10 or more CPUs the 20 spinning readers exceed that test'sbaseline+15allowance, so it fails (baseline=3, final=24). On CI's 4-CPU runner the 8 spinning readers still use up most of the allowance, which leaves little room to catch a real daemon leak.Fix
net.ErrClosedwitherrors.Is.Closehas begun (s.done).Tests
TestCloseStopsReadersstarts a server, closes it, and waits for the goroutine count to return to baseline.goroutines still running after Close: base=2 running=36 now=22base=2 running=36 after Close=2go test -race ./...passes on macOS arm64. On Linux arm64 (10 CPUs) the package passes some runs and fails others, onorigin/maintoo, because of an existing data race:EnableCompatWSS(server.go:302) writes a field thatdispatchRelay(server.go:900) reads, inTestEnableCompatWSS_HappyPath. Once the race detector trips, every test running concurrently is marked failed. That race is separate from this change and isn't fixed here. With the fix the package's Linux run also drops from 61-104 s to about 17 s, because closed test beacons no longer spin.🤖 Generated with Claude Code