Middle — Middle+
How to correctly implement a safe system shutdown without data loss and with minimal downtime?
sobes.tech AI
Answer from AI
To safely shut down a system written in Go without data loss and with minimal downtime, the following approaches are usually used:
-
Handling OS signals (e.g., SIGINT, SIGTERM) using the
os/signalpackage. This allows for proper detection of shutdown requests. -
Using
context.Contextto manage the lifetime of goroutines and cancel operations. -
Graceful shutdown — sequentially terminating operations:
- Stop accepting new requests (e.g., close the HTTP server).
- Wait for current operations to finish.
- Save state and free resources.
Example:
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"time"
)
func main() {
srv := &http.Server{Addr: ":8080"}
// Run server in a separate goroutine
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("ListenAndServe(): %v", err)
}
}()
// Channel for signals
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt)
<-quit // Wait for signal
log.Println("Shutting down server...")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatalf("Server Shutdown Failed:%+v", err)
}
log.Println("Server exited properly")
}
This approach allows for proper shutdown, waiting for current requests to finish, and avoiding data loss.