Group 为处理各个子任务协程的管理集合
type Group struct{
cancel func()
wg sync.WaitGroup
errOnce sync.Once
err error
}
WithContex()会返回一个新Group和ctx衍生的新的context,
WithContex()一但返回非空err或者Wait()返回数据,这个衍生的ctx生命周期结束。
func WithContext(ctx context.Context) (*Group, context.Context) {
ctx, cancel := context.WithCancel(ctx)
return &Group{cancel: cancel}, ctx
}
核心方法Wait()
func (g *Group) Wait() {
g.wg.Wait()
g.cancel != nil {
g.cancel()
}
return g.err
}
Wait()方法会阻塞主进程,直到所有Go()函数都返回
如果所有Go()返回err都为空,说明执行成功;如果有Go()返回err不为空,则返回第一个返回err不为空的err。
核心方法Go()
func (g *Group) Go(f func() Error) {
g.wg.Add(1)
go func() {
defer g.wg.Done()
if err := f(); err != nil {
g.errOnce.Do(func() {
g.err = err
g.cancel != nil{
g.cancel()
}
})
}
}()
}
在新的协程中调用输入的函数,如果err不为空,会执行cancel函数,err由Wait()函数返回。
应用示例
var eg errgroup.Group
eg.Go(func() error {
var err error
as, err = r.Service.CallA(ctx, a)
if err != nil {
//log
return err
}
return nil
})
eg.Go(func() error {
var err error
bs, err = r.Service.CallB(ctx, b)
if err != nil {
//log
return err
}
return nil
})
if err = eg.Wait(); err != nil {
return nil, err
}