Skip to content

Instantly share code, notes, and snippets.

@sanderhahn
Last active December 26, 2019 07:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sanderhahn/a865490826499fcae9ebef4ea0addf16 to your computer and use it in GitHub Desktop.
Save sanderhahn/a865490826499fcae9ebef4ea0addf16 to your computer and use it in GitHub Desktop.
Graceful Server Shutdown in Go
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"os"
"os/signal"
"time"
)
func countdown(w http.ResponseWriter, r *http.Request) {
var flush func()
if f, ok := w.(http.Flusher); ok {
flush = func() {
f.Flush()
}
}
io.WriteString(w, "Countdown initiated...\n")
for i := 10; i > 0; i-- {
flush()
time.Sleep(1 * time.Second)
fmt.Fprintf(w, "%d\n", i)
}
io.WriteString(w, "BOOM!\n")
}
func main() {
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
addr := "127.0.0.1:" + port
mux := http.NewServeMux()
mux.HandleFunc("/", countdown)
server := http.Server{
Addr: addr,
Handler: mux,
ReadTimeout: 60 * time.Second,
WriteTimeout: 60 * time.Second,
}
go func() {
log.Printf("Started listening on: http://%s/", server.Addr)
err := server.ListenAndServe()
if err != http.ErrServerClosed {
log.Fatal(err)
}
}()
<-stop
timeout := 30 * time.Second
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
log.Printf("Shutting down...")
server.Shutdown(ctx)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment