errgroup
I’m a big fan of the Go stdlib sync/errgroup package.
The errgroup.Group type makes it trivial to manage multiple worker goroutines that
all need to succeed, and often obviates the need for sync.WaitGroup.
However, both in personal and client projects, I regularly ran into the issue where I wanted to rate-limit the number of simultaneous goroutines. An example would be where the goroutines are calling a backend API (or DB) that itself has rate limits.
I created the neilotoole/errgroup package
as a drop-in replacement for stdlib errgroup. You use it like so:
import "github.com/neilotoole/errgroup"
func main() {
numG, qSize := 8, 4
g, ctx := errgroup.WithContextN(ctx, numG, qSize)
g.Go(func() error {
// do something
return nil
})
}
The numG and qSize params control the gating behavior of the Group. In
benchmarks, this implementation often outperforms stdlib errgroup, but obviously
take your own benchmarks for your specific workload.
UPDATE 2023-01-10: The Go team have updated
sync/errgroupwith aGroup.SetLimitmethod, which eliminates the need for my implementation (and their implementation is superior too). You should usesync/errgroupinstead; I’m happily retiringneilotoole/errgroup.