# Golang errgroup




## 介绍

[errgroup](https://pkg.go.dev/golang.org/x/sync/errgroup) 是Go语言的一个包，用于管理和协调多个并发任务，当其中任意一个任务出错时，可以及时结束所有任务，并返回错误信息。

```mermaid
flowchart LR
    E[errgroup]
    A[Task Goroutine 1]
    B[Task Goroutine 2]
    C[Task Goroutine 3]
    E --> A
    E --> B
    E --> C
```

## 运行模式

errgroup 有两种运行模型，开启任务后，如果遇到有 Goroutine 报错

- 一种是继续执行其它任务
- 另一种是取消其它的任务



**继续执行其它任务**

```go
g := new(errgroup.Group)
```


**取消其它的任务**

```go
func main() {
	eg, ctx := errgroup.WithContext(context.Background())
	eg.Go(func() error {
		select {
		case <-ctx.Done():
		default:
			return errors.New("eg 1 err")
		}
		return nil
	})
	eg.Go(func() error {
		time.Sleep(1 * time.Second)
		select {
		case <-ctx.Done():
		default:
			fmt.Println("eg 2")
		}
		return nil
	})
	if err := eg.Wait(); err != nil {
		fmt.Println(err)
	}
}
```



## 问题

1. 没有处理 panic。 
2.  ~~没有控制并发 goroutine 数量~~ 新版本中有 `SetLimit` 控制 goroutine 数量。
3. 如果内部报错，errgroup 会调用 `g.cancel`，如果在外面使用这个返回的 context，会报错。

推荐使用[这个](https://pkg.go.dev/github.com/go-kratos/kratos/pkg/sync/errgroup)。

