Problem
It can sometimes be useful to run code before the application shuts down. This code could handle removing temporary files, flushing changes, etc.
While it is impossible to ensure this code is always executed (e.g. the system running the app could crash), it can be useful to add code to handle a graceful shutdown in the general case.
Solution
func main() {
setupGracefulShutdown()
// ...
}
func setupGracefulShutdown() {
// Create chanel for OS signals
var signals = make(chan os.Signal)
// Configure which OS signals to be put in the chanel
signal.Notify(signals, syscall.SIGTERM)
signal.Notify(signals, syscall.SIGINT)
// Listen for signals in the background
go func() {
sig := <-signals
log.Printf("caught signal: %+v", sig)
// TODO: anything necessary for a graceful shutdown
os.Exit(0)
}()
}
Details
In this context, "graceful shutdown" means giving the application code time to exit smoothly and correctly.
For example, this could include saving any internal cache out to a file/database, closing any open database connections, or completing any requests still in progress. It really depends on the application.
The code above introduces a location where all this code can be triggered just after an OS signal is received and just before the application closes down.