Published
- 2 min read
sync/errgroup
Background
Unlike its name suggests, this library isn’t about errors.
sync/errgroup
reduces the number of lines needed to write bounded concurrent code.
ELI5 Why we need it
Imagine functionalities being food items in a burger chain.
- Creating a new goroutine -> Ordering a burger
- Making goroutines bounded with semaphores -> Ordering fries
- Waiting until goroutines are done using
sync.WaitGroup
-> Ordering a drink
These are common food items that most people would like to have for every meal. Hence, most burger chains offer **a meal/combo that costs less **than ordering each item individually.
This is where sync/errgroup
comes in, reducing the number of lines needed.
How to use it
First, let us go back and see what the code looks like without sync/errgroup
:
func withoutErrGroup() {
sem := semaphore.NewWeighted(10) // init semaphores with 10 concurrency
wg := sync.WaitGroup{} // declare waitGroup
for i := 0 ; i< 100 ; i++ {
wg.Add(1) // increment waitGroup count
go func () {
sem.Acquire(context.Background(), 1) // try to acquire a semaphore (permission to run)
time.Sleep(1 * time.Second) // code you want each goroutine to run
wg.Done() // notifying waitGroup that this goroutine has completed
sem.Release(1) // releasing semaphore for other goroutines to use
}()
}
wg.Wait() // blocking wait for all goroutines to be completed
}
VS what the code looks like with sync/errgroup
:
func withErrGroup() {
wg := errgroup.Group{} // declare waitGroup
wg.SetLimit(10) // limit concurrency to 10
for i := 0 ; i< 100 ; i++ {
wg.Go(func() error {
time.Sleep(1 * time.Second) // code you want each goroutine to run
return nil
})
}
wg.Wait()// blocking wait for all goroutines to be completed
}
sync/errgroup
eliminates commonly used and repeated code, making our code easier to read and understand.
Rabbit Hole
sync/errgroup
provides a kill switch for all goroutines via context cancelation.
Great for tasks that could be cancelled/killed.
Alright, that is all for today. Let’s get one post smarter every day, and see you tomorrow! wg.Wait()