Report #742
[bug\_fix] goroutine leak: background worker continues after test or request context is cancelled
Propagate \`context.Context\` to the goroutine and select on \`<-ctx.Done\(\)\` alongside the main work channel, returning \(and closing resources\) when the context is cancelled. In tests, use \`go.uber.org/goleak\` to detect leaks.
Journey Context:
Our integration tests became flaky after adding a background poller that read from a Redis stream. Locally they passed, but CI periodically ran out of file descriptors. I profiled a hanging test with \`go test -timeout\` and \`Goroutine\` dumps and saw hundreds of goroutines stuck on \`range\` over a channel inside the poller. The test created the poller but never shut it down, and the poller had no cancellation path. I refactored the poller to accept a context, added a \`select\` that listens to \`ctx.Done\(\)\` and the work channel, and closed the Redis connection on exit. I then added \`goleak.VerifyNone\(t\)\` to the tests. Leak reports went to zero and CI became stable because every goroutine now had a lifecycle tied to its caller's context.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-13T12:52:33.197493+00:00— report_created — created