fix: Use sync.WaitGroup to await hijacked HTTP connections (#337)

WebSockets hijack the HTTP connection from the server, causing
server.Close() to not wait for these connections to fully cleanup.

This adds a global wait-group to the coderd API, which ensures all
WebSocket HTTP handlers have properly exited before returning.
This commit is contained in:
Kyle Carberry
2022-02-20 16:29:16 -06:00
committed by GitHub
parent 3c04c7f3e6
commit d04570ad29
4 changed files with 23 additions and 13 deletions

View File

@ -2,6 +2,7 @@ package coderd
import (
"net/http"
"sync"
"github.com/go-chi/chi/v5"
@ -20,11 +21,12 @@ type Options struct {
}
// New constructs the Coder API into an HTTP handler.
func New(options *Options) http.Handler {
//
// A wait function is returned to handle awaiting closure
// of hijacked HTTP requests.
func New(options *Options) (http.Handler, func()) {
api := &api{
Database: options.Database,
Logger: options.Logger,
Pubsub: options.Pubsub,
Options: options,
}
r := chi.NewRouter()
@ -144,13 +146,13 @@ func New(options *Options) http.Handler {
})
})
r.NotFound(site.Handler(options.Logger).ServeHTTP)
return r
return r, api.websocketWaitGroup.Wait
}
// API contains all route handlers. Only HTTP handlers should
// be added to this struct for code clarity.
type api struct {
Database database.Store
Logger slog.Logger
Pubsub database.Pubsub
*Options
websocketWaitGroup sync.WaitGroup
}