In Go, you can gracefully exit a program and handle errors during shutdown using a combination of signals, goroutines, and channels. Here's an example:
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
// Create a channel to receive signals
signals := make(chan os.Signal, 1)
signal.Notify(signals, os.Interrupt, syscall.SIGTERM)
// Create a channel to handle shutdown completion
done := make(chan bool)
// Start a goroutine to handle shutdown
go func() {
// Handle any cleanup tasks before the program exits
defer fmt.Println("Cleanup tasks...")
// Perform your shutdown logic here
time.Sleep(3 * time.Second) // Simulating a cleanup task
// Notify that shutdown is complete
done <- true
}()
// Wait for the program to exit or receive a shutdown signal
select {
case <-done:
fmt.Println("Graceful shutdown completed")
case sig := <-signals:
fmt.Println("Received signal:", sig)
os.Exit(1)
}
// Finish program execution
fmt.Println("Program exit")
}
In this example:
signals
to receive signals (e.g., Interrupt or SIGTERM) for graceful shutdown.done
for handling shutdown completion.done
channel after the shutdown tasks are completed.done
channel to receive a value or the signals
channel to receive a signal.By using this approach, you can gracefully exit your program and handle any errors or interruptions during shutdown.