github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/goutils/cobrau/catch_interrupt.go (about) 1 /* 2 * Copyright (c) 2023-present unTill Pro, Ltd. 3 * @author Maxim Geraskin 4 */ 5 6 package cobrau 7 8 import ( 9 "context" 10 "os" 11 "os/signal" 12 "sync" 13 14 "github.com/spf13/cobra" 15 "github.com/voedger/voedger/pkg/goutils/logger" 16 ) 17 18 func ExecCommandAndCatchInterrupt(cmd *cobra.Command) error { 19 20 cmdExec := func(ctx context.Context) (err error) { 21 err = cmd.ExecuteContext(ctx) 22 return 23 } 24 25 return goAndCatchInterrupt(cmdExec) 26 27 } 28 29 func goAndCatchInterrupt(f func(ctx context.Context) error) (err error) { 30 31 var signals = make(chan os.Signal, 1) 32 33 ctx, cancel := context.WithCancel(context.Background()) 34 signal.Notify(signals, os.Interrupt) 35 36 wg := sync.WaitGroup{} 37 wg.Add(1) 38 go func() { 39 defer wg.Done() 40 err = f(ctx) 41 cancel() 42 }() 43 44 select { 45 case sig := <-signals: 46 logger.Info("signal received:", sig) 47 cancel() 48 case <-ctx.Done(): 49 } 50 logger.Verbose("waiting for function to finish...") 51 wg.Wait() 52 return err 53 }