Как отменять группу горутин через errgroup.WithContext в Go

Как отменять группу горутин через errgroup.WithContext в Go
Содержание статьи

Когда несколько операций составляют одну работу, удобнее вернуть общую ошибку и сообщить остальным, что задачу пора остановить. 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.

Похожие статьи по данной теме