package main import ( "context" "log" "os" "os/signal" "syscall" "time" ) type Runnable func(ctx context.Context) error func Run(ctx context.Context, runnable ...Runnable) { ctx, cancel := context.WithCancel(ctx) defer cancel() errCh := make(chan error, len(runnable)) for _, r := range runnable { go func(run Runnable) { if err := run(ctx); err != nil { errCh <- err } }(r) } sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) select { case sig := <-sigCh: log.Println("shutdown signal:", sig) case err := <-errCh: log.Println("runtime error:", err) } cancel() time.Sleep(2 * time.Second) }