48 lines
1.1 KiB
Go
48 lines
1.1 KiB
Go
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
|
|
}
|
|
}
|