package gopackagebase import ( "context" "log" "os" "os/signal" ) func InitSignalHandler() (context.Context, func()) { // Setup some initial context for gracefully killing the program // with system interrupt signals like ctrl+c // https://pace.dev/blog/2020/02/17/repond-to-ctrl-c-interrupt-signals-gracefully-with-context-in-golang-by-mat-ryer.html ctx := context.Background() ctx, cancel := context.WithCancel(ctx) signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, os.Interrupt) // Start a goroutine to listen for signal interrupts go func() { select { case <-signalChan: // Graceful exit on ctrl+c log.Printf("Attempting to exit gracefully...\n") cancel() case <-ctx.Done(): } <-signalChan // Hard exit on second ctrl+c log.Printf("Hard kill\n") os.Exit(2) }() // Return a new cancel function that also sends the stop signal. killFunc := func() { signal.Stop(signalChan) cancel() } return ctx, killFunc }