


Когда несколько операций составляют одну работу, удобнее вернуть общую ошибку и сообщить остальным, что задачу пора остановить. errgroup.WithContext создаёт группу и контекст для этого сценария. В примере Mentoring.digital одновременно запускается до трёх проверок.
Первая ошибка, которую вернула работа в группе, отменяет её контекст. Wait() ждёт завершения запущенных функций и возвращает первую ненулевую ошибку, если такая была. Контекст также отменяется после завершения Wait(). Передавайте производный контекст только операциям внутри группы.
func checkBatch(
parent context.Context,
ids []string,
check func(context.Context, string) error,
) error {
group, ctx := errgroup.WithContext(parent)
group.SetLimit(3)
for _, id := range ids {
if ctx.Err() != nil {
break
}
id := id
group.Go(func() error {
if err := ctx.Err(); err != nil {
return err
}
return check(ctx, id)
})
}
if err := group.Wait(); err != nil {
return err
}
return parent.Err()
}
Для примера нужны пакеты context и golang.org/x/sync/errgroup. Пока заняты все места, очередной вызов Go может ждать. Проверка внутри функции учитывает случай, когда контекст отменился за время этого ожидания. Лимит задаётся до запуска работ.
Подставьте тестовую функцию, которая для одного идентификатора возвращает известную ошибку, а остальные работы ожидают отмены через ctx.Done(). Проверьте ошибку группы и завершение функций. В рабочем коде передавайте контекст в запросы и обрабатывайте отмену там, где это поддерживает используемая операция.
Такой сценарий можно собрать на занятиях по Go. Если нужно выбрать ограничение под несколько внешних сервисов, обсудите их договорённости и тайм-ауты с ментором по Go.