Julien's dev blog

HTTP with Go: Graceful Shutdown

Implementing graceful HTTP shutdown with Golang.

Last updated on: 2024-12-12

Graceful shutdown implementation for a Go HTTP server:

func run() (exitcode int) {
    // Listen for interrupt signal (and notify context when received).
    mainCtx, mainCtxCancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
    defer mainCtxCancel()

    // Initialize HTTP server.
    httpServer := &http.Server{ /* TODO */ }
    httpServer.BaseContext = func(_ net.Listener) context.Context { return mainCtx }

    // Run HTTP server in seperate Go routine.
    httpErrc := make(chan error, 1)
    go func() {
        err := httpServer.ListenAndServe()
        if err != nil && !errors.Is(err, http.ErrServerClosed) {
            httpErrc <- err
        }
    }()

    // Wait for interrupt signal or server error.
    select {
    case err := <-httpErrc:
        logger.Error("HTTP server exited", "error", err)
    case <-mainCtx.Done():
        logger.Debug("received exit signal", "cause", mainCtx.Err())
    }
    exitCtx, exitCtxCancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer exitCtxCancel()

    // Shutdown HTTP server.
    err := httpServer.Shutdown(exitCtx)
    if err != nil { logger.Error("HTTP shutdown failed", "error", err) }

    // Do other cleanup tasks (ex: closing database connection).
    // ...
}
Go code

Using the previous code, you can be notified of interrupts in your HTTP handlers via the request's context (`http.Request.Context()`).

For example, this handler will block until an interrupt:

func handle(w http.ResponseWriter, r *http.Request) {
    <-r.Context().Done()
}
Go code

NB: As part of the default `http.Server` behavior, if the HTTP client closes the underyling network connection, the request's context is also done.

References

https://pkg.go.dev/os/signal#NotifyContext https://pkg.go.dev/net/http#Server.Shutdown https://pkg.go.dev/net/http#Request.Context https://www.rudderstack.com/blog/implementing-graceful-shutdown-in-go