-
-
Save faabiosr/6f7078224c9ed317764a000ddf6d9563 to your computer and use it in GitHub Desktop.
Example for using go's sync.errgroup together with signal detection signal.NotifyContext to stop all running goroutines
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"errors" | |
"fmt" | |
"os/signal" | |
"syscall" | |
"time" | |
"golang.org/x/sync/errgroup" | |
) | |
func main() { | |
ctx, done := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGKILL) | |
defer done() | |
g, gctx := errgroup.WithContext(ctx) | |
// just a ticker every 2s | |
g.Go(func() error { | |
ticker := time.NewTicker(2 * time.Second) | |
i := 0 | |
for { | |
i++ | |
if i > 10 { | |
return nil | |
} | |
select { | |
case <-ticker.C: | |
fmt.Println("ticker 2s ticked") | |
case <-gctx.Done(): | |
fmt.Println("closing ticker 2s goroutine") | |
return gctx.Err() | |
} | |
} | |
}) | |
// just a ticker every 1s | |
g.Go(func() error { | |
ticker := time.NewTicker(1 * time.Second) | |
i := 0 | |
for { | |
i++ | |
if i > 10 { | |
return nil | |
} | |
select { | |
case <-ticker.C: | |
fmt.Println("ticker 1s ticked") | |
case <-gctx.Done(): | |
fmt.Println("closing ticker 1s goroutine") | |
return gctx.Err() | |
} | |
} | |
}) | |
// force a stop after 15s | |
time.AfterFunc(15*time.Second, func() { | |
fmt.Println("force finished after 15s") | |
done() | |
}) | |
// wait for all errgroup goroutines | |
err := g.Wait() | |
if err != nil { | |
if errors.Is(err, context.Canceled) { | |
fmt.Println("context was canceled") | |
} else { | |
fmt.Printf("received error: %v\n", err) | |
} | |
} else { | |
fmt.Println("finished clean") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment