[Golang] errgroup使用例

ループでgoroutineをぶん回してる時に一つでもエラーが起きたら他のすべてのタスクを終了してエラーを返す例

package main

import (
    "context"
    "errors"
    "fmt"
    "log"

    "golang.org/x/sync/errgroup"
)

func main() {
    eg, ctx := errgroup.WithContext(context.Background())
    ctx, cancel := context.WithCancel(ctx)
    defer cancel()

    for i := 0; i < 100; i++ {
        i := i
        eg.Go(func() error {
            select {
            case <-ctx.Done():
                return nil
            default:
                fmt.Println(i)

                if i == 20 {
                    return errors.New("Error occurred")
                }

                return nil
            }
        })
    }

    if err := eg.Wait(); err != nil {
        cancel()
        log.Fatal(err)
    }

    fmt.Println("Complete!")
}

goroutineで実行するタスクの最大数を制限したい場合は以下のように書く

limit := make(chan struct{}, 5}
for i := 0; i < 100; i++ {
    i := i
    eg.Go(func() error {
        limit <- struct{}{}
        defer func() { <-limit }()

        select {
     
    })
}