Graceful shutdown đợi các request đang xử lý hoàn thành trước khi thoát process, tránh mất data hoặc trả 502 cho client.
go
srv := &http.Server{Addr: ":8080", Handler: mux}
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal(err)
}
}()
// Bắt SIGINT / SIGTERM (Ctrl+C, kubectl rollout, docker stop)
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
// Cho phép request đang chạy 30s để hoàn thành
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatalf("forced shutdown: %v", err)
}