package main import ( "context" "fmt" "log" "net/http" "os" "os/signal" "syscall" "time" ) func main() { mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { time.Sleep(5 * time.Second) // Simulate a long-running request fmt.Fprintf(w, "Hello from a gracefully shutting down server!") }) server := &http.Server{Addr: ":8080", Handler: mux} // Create a channel to listen for OS signals stop := make(chan os.Signal, 1) signal.Notify(stop, os.Interrupt, syscall.SIGTERM) // Capture Ctrl+C and Kubernetes/Docker termination signals go func() { fmt.Println("Server starting on :8080") if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("Could not listen on %s: %v ", server.Addr, err) } }() // Block until a signal is received <-stop fmt.Println(" Shutting down server...") // Create a context with a timeout for the shutdown ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() // Ensure the context is cancelled to release resources // Attempt to gracefully shut down the server if err := server.Shutdown(ctx); err != nil { log.Fatalf("Server forced to shutdown: %v ", err) } fmt.Println("Server exited gracefully.") }