errgroup:有限并发与错误传播的惯用法

手写 WaitGroup + 错误 channel 容易漏边角。errgroup 把「并发、限流、取消」收成一小段可读代码。

golang.org/x/sync/errgroup 适合:一组子任务,任一失败则取消其余,并返回第一个非 nil 错误。

基本形态

g, ctx := errgroup.WithContext(parent)
g.SetLimit(8)

for _, u := range urls {
    u := u
    g.Go(func() error {
        return fetch(ctx, u)
    })
}

if err := g.Wait(); err != nil {
    return err
}

语义要点

  • WithContext 派生可取消 ctx;首个错误触发 cancel。
  • SetLimit 限制同时运行的 goroutine 数,保护下游。
  • Wait 等待全部结束,返回第一个错误(其余错误被丢弃——若需聚合要自己收集)。

何时不用

需要「尽量完成全部并汇总所有错误」、或任务之间有复杂管道背压时,pipeline + 显式错误切片可能更清晰。errgroup 擅长的是「全有或快速失败」。

小结

限流用 SetLimit,生命周期用 WithContext,失败即停用首错取消。把并发样板从业务逻辑里拿掉,代码会安静许多。