errgroup是一个很简单的工具包,总共代码量加上注释和空行才100来行
作用就是方便执行的任务,比如
g := errgroup.Group{}
g.Go(func1)
g.Go(func2)
if err := g.Wait(); err != nil {
//...
}
结构
type Group struct {
cancel func() //context 取消函数
wg sync.WaitGroup //用来等待全部执行完成
sem chan token //用来控制并发数
errOnce sync.Once //控制err字段只赋值一次
err error //错误
}
主要函数
func (g *Group) Go(f func() error) {
if g.sem != nil {
g.sem <- token{} //限制并发数, 并发数由管道能容纳下的token个数决定
}
g.wg.Add(1)
go func() {
defer g.done()
if err := f(); err != nil {
g.errOnce.Do(func() { //如果出错后只赋值一次err
g.err = err
if g.cancel != nil { //如果使用的是WithContext,这个字段会有值, 调用取消函数
g.cancel()
}
})
}
}()
}
主要的东西就这么点, 可以看到errgroup还是一个很简洁的小工具, 配合singleflight一起使用挺不错