SetLimit и границы errgroup
Без ограничений errgroup запускала всё сразу — на пачке из тысяч файлов снова вырастала тысяча горутин. Миша добавил SetLimit, и группа превратилась в аккуратный пул со встроенным лимитом.
SetLimit превращает errgroup в лёгкий worker pool: не больше N функций одновременно, а блокируется при исчерпании лимита сама вызывающая горутина.
Лимит параллелизма
g, ctx := errgroup.WithContext(ctx)
g.SetLimit(8)
for _, f := range files {
f := f
g.Go(func() error {
return upload(ctx, f)
})
}
g.Wait()
С лимитом 8 одновременно работает не больше восьми функций. Остальные не «встают в очередь» — блокируется сама горутина, вызвавшая Go, до тех пор, пока не освободится слот. Внутри это обычный семафор на канале — та же техника, что в следующем уроке: Go отправляет токен, завершённая функция возвращает его.
Errgroup как пул
SetLimit превращает errgroup в лёгкий worker pool из: ограниченный параллелизм плюс готовый сбор ошибок и отмена по первому сбою. Для пачки однотипных задач это короче и безопаснее самописного пула с каналами и WaitGroup.
TryGo
Если блокироваться в Go не хочется, есть TryGo: при исчерпанном лимите он вернёт false, вместо того чтобы ждать. Удобно, когда лимит — это «сколько ещё можем принять», а не «сколько будем ждать».
Вы узнаете:
- что делают
SetLimit(-1)иSetLimit(0) - как
TryGoреализует backpressure
Проверьте себя
Что означает g.SetLimit(8)?
Что делают SetLimit(0) и SetLimit(-1)?
Меняет ли лимит результат errgroup?
правильных ответов
SetLimit(N) — семафор внутри errgroup: N одновременных функций, Go блокируется на полном лимите, TryGo — неблокирующая попытка. Лимит снимает отрицательное значение, а не ноль.
10 000 ₽ · 60 минут · онлайн