package common import ( "context" "os" "os/signal" "syscall" "time" "github.com/rs/zerolog/log" "github.com/spf13/cobra" ) func Start(cmd *cobra.Command) { ctx, cancel := context.WithCancel(context.Background()) returnCode := make(chan int) terminated := make(chan interface{}) go trapSignals(cancel, terminated, returnCode) if err := cmd.ExecuteContext(ctx); err != nil { log.Error().Err(err).Send() sendReturnCode(returnCode, -2) } else { sendReturnCode(returnCode, 0) } close(terminated) os.Exit(<-returnCode) } func sendReturnCode(returnCode chan<- int, code int) { go func(returnCode chan<- int) { returnCode <- code }(returnCode) } func trapSignals(cancel context.CancelFunc, terminated chan interface{}, returnCode chan int) { stopSignal := make(chan os.Signal, 1) signal.Notify(stopSignal, syscall.SIGTERM, syscall.SIGINT) <-stopSignal log.Info().Msg("received stop signal. shutting down...") cancel() select { case <-time.After(30 * time.Second): log.Warn().Msg("app shutdown sequence timed out") returnCode <- 1 case <-terminated: returnCode <- 0 } }