Skip to content

fix(server): close Consume race on returnError and stopForLoop teardown#97

Draft
miotte wants to merge 1 commit into
mainfrom
miotte-pr6
Draft

fix(server): close Consume race on returnError and stopForLoop teardown#97
miotte wants to merge 1 commit into
mainfrom
miotte-pr6

Conversation

@miotte
Copy link
Copy Markdown
Contributor

@miotte miotte commented May 22, 2026

Fixes #95

Summary

  • Wait for the sender and Subscribe goroutines before Consume returns, so the deferred close+nil of stopForLoop can't race against in-flight reads.
  • Make stopForLoop carry the error itself, leaving the main path as the sole writer of returnError.
  • Order the defers so loopCancel signals first, wg.Wait drains the goroutines next, and the channels close last with no writers left.

Test plan

  • go test ./internal/server/... -race
  • Full go test ./... -race

Consume spawned sender and Subscribe goroutines that wrote to returnError
and read stopForLoop through heap-escaped pointers, then returned without
waiting for them. The goroutines kept running past Consume's return,
racing against its writes to returnError and its deferred close+nil of
stopForLoop.

Wait for those goroutines before returning, and make stopForLoop carry
the error itself so main is the sole writer of returnError. The defers
are ordered so loopCancel signals first, wg.Wait drains the goroutines
next, and the channels close last with no writers left.

Signed-off-by: Michael Otteni <MichaelGOtteni@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Race in server.Consume between teardown and spawned goroutines

1 participant