#errgroup.WithContext()を使ってTimeoutでgoroutineを終了する
下記のコードではGoのerrgroup.WithContext()を使って、 goroutine内でerrorが発生した場合やTimeoutが発生した場合にgoroutineを終了するようにしています。
package main
import (
"context"
"fmt"
"log"
"time"
"golang.org/x/sync/errgroup"
)
func createWorker(ctx context.Context, i int) func() error {
worker := func() error {
fmt.Printf("before: i = %d\n", i)
if i == 3 {
// goroutine内でerrorにするには以下のコードのコメントをはずします。
// return fmt.Errorf("i is %d", i)
return nil
}
time.Sleep(time.Duration(i) * 100 * time.Millisecond)
select {
case <-ctx.Done():
return ctx.Err()
default:
fmt.Printf("after: i = %d\n", i)
}
return nil
}
return worker
}
func main() {
// Timeoutにするには以下のコードのコメントをはずします。
// ms := 200 * time.Millisecond
ms := 2000 * time.Millisecond
_ctx, cancel := context.WithTimeout(context.Background(), ms)
defer cancel()
eg, ctx := errgroup.WithContext(_ctx)
for i := 0; i < 5; i++ {
eg.Go(createWorker(ctx, i))
}
if err := eg.Wait(); err != nil {
log.Fatal(err)
}
fmt.Println("end")
}