Handling signals in Go #
A common pattern in Go is to wait for the user (or a scheduler like Kubernetes) to terminate the process. Consider the following use case where we run a HTTP server.
package main
import (
"context"
"fmt"
"net/http"
"os"
"os/signal"
"time"
)
func main() {
http.HandleFunc("/hello", func(rw http.ResponseWriter, r *http.Request) {
rw.WriteHeader(http.StatusOK)
})
srv := &http.Server{
Handler: http.DefaultServeMux,
Addr: ":8080",
}
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
fmt.Printf("Failed to serve: %v\n", err)
}
}()
ch := make(chan os.Signal, 1)
signal.Notify(ch, os.Interrupt)
fmt.Println("Waiting for signal..")
<-ch
fmt.Println("Exiting..")
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
fmt.Printf("Failed to shutdown http server: %v\n", err)
}
}