go.missing_graceful_shutdown
Stability
High
Detects HTTP servers that don’t handle SIGTERM for graceful shutdown, causing dropped requests during deployments.
Why It Matters
Section titled “Why It Matters”Without graceful shutdown:
- Dropped requests — In-flight requests are terminated mid-processing
- Data loss — Partial writes, uncommitted transactions
- Connection errors — Clients receive connection reset errors
- Deployment failures — Rolling updates cause user-visible errors
Example
Section titled “Example”// ❌ Before (no graceful shutdown)func main() { http.ListenAndServe(":8080", handler)}// ✅ After (graceful shutdown)func main() { server := &http.Server{ Addr: ":8080", Handler: handler, }
// Start server in goroutine go func() { if err := server.ListenAndServe(); err != http.ErrServerClosed { log.Fatal(err) } }()
// Wait for interrupt signal quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit
// Graceful shutdown with timeout ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel()
if err := server.Shutdown(ctx); err != nil { log.Fatal("Server forced to shutdown:", err) } log.Println("Server exited gracefully")}What Unfault Detects
Section titled “What Unfault Detects”http.ListenAndServe()without signal handling- Missing
server.Shutdown()calls log.Fatal()in signal handlers (prevents cleanup)- Hardcoded exits without cleanup
Auto-Fix
Section titled “Auto-Fix”Unfault generates patches that add signal handling and graceful shutdown:
import ( "context" "os" "os/signal" "syscall")
// Graceful shutdown setupquit := make(chan os.Signal, 1)signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)Kubernetes Configuration
Section titled “Kubernetes Configuration”spec: terminationGracePeriodSeconds: 30 containers: - name: app lifecycle: preStop: exec: command: ["/bin/sh", "-c", "sleep 5"]