Skip to content

fix(http-server): remove data race between Start and Shutdown - #9

Open
rzatonskiy wants to merge 4 commits into
gozix:masterfrom
rzatonskiy:fix/http-server-data-race
Open

rzatonskiy wants to merge 4 commits into
gozix:masterfrom
rzatonskiy:fix/http-server-data-race

Conversation

@rzatonskiy

Copy link
Copy Markdown

The http-server command declared a named result and wrote to it from two goroutines:
e.Start in the serving goroutine and e.Shutdown after the context cancellation. Every
graceful stop raced, and the command returned nil or http.ErrServerClosed depending on
which write landed last.

  • pass the e.Start result through a buffered channel instead of the named result
  • treat http.ErrServerClosed as a clean stop and return nil
  • return an early start failure without waiting for the context, instead of hanging
    until the process is interrupted
  • resolve every server before starting any of them, so a resolve failure cannot leave
    a started server behind and the container is not resolved concurrently
  • join the serving goroutine before returning, unless the shutdown itself failed
  • cover the behaviour with tests and run the suite under the race detector

The CI matrix was pinned to go 1.18/1.19 while go.mod requires go 1.23.0, so it is
raised to 1.23-1.27.

* pass the e.Start result through a buffered channel instead of the named result
* treat http.ErrServerClosed as a clean stop and return nil
* return an early start failure without waiting for the context
* join the serving goroutine after the shutdown and report its error
* cover both paths with tests runnable under -race
* add -race to the test script, so a reintroduced race fails the build
* raise the go matrix to 1.23-1.27, the module requires go 1.23.0
* the di container is not safe for concurrent resolution, do it sequentially
* a resolve failure now fails before a single server is started, so no server
  is left running behind an error
…utdown

* report a shutdown failure as is: the listener may still be open, and echo.Shutdown
  gives up on the plain server whenever the TLS one fails, so the join would hang
* pin the start failure down to a listen error in the test, not to any error at all
* assert the address is free once the command returned, so a shutdown that never
  happened cannot pass
* keep the echo banner out of the test output and stop sharing the default transport
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.

1 participant