How to gracefully exit a program and handle errors during shutdown in Go?

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:

  1. We create a channel signals to receive signals (e.g., Interrupt or SIGTERM) for graceful shutdown.
  2. We create a channel done for handling shutdown completion.
  3. We start a goroutine to handle shutdown logic. This could include cleanup tasks or any necessary closing of resources.
  4. The shutdown goroutine sends a value to the done channel after the shutdown tasks are completed.
  5. We use a select statement to wait for the done channel to receive a value or the signals channel to receive a signal.
  6. If the program receives a shutdown signal, it prints the signal received and exits with a non-zero status code.
  7. If the program completes the shutdown tasks, it prints a completion message.
  8. Finally, it prints a message indicating the program exit.

By using this approach, you can gracefully exit your program and handle any errors or interruptions during shutdown.