sync/errgroup Go: guia completo com exemplos práticos

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

sync/errgroup para Go: guia completo com exemplos práticos

1. O que é e para que serve

A biblioteca sync/errgroup faz parte da extensão oficial golang.org/x/sync e oferece uma maneira poderosa e elegante de gerenciar goroutines concorrentes com tratamento de erros. Na biblioteca padrão do Go, existe o pacote sync com WaitGroup, mas ele não coleta erros das goroutines. O errgroup resolve esse problema: você inicia várias goroutines e, se pelo menos uma delas retornar um erro, o grupo sinaliza imediatamente (ou ao final de todas), cancelando o contexto e permitindo que as outras goroutines sejam encerradas corretamente.

Para que serve isso? Em aplicações reais, é comum executar várias tarefas independentes em paralelo: baixar arquivos, processar dados, fazer requisições a APIs. Se uma tarefa falhar, não faz sentido continuar as outras — é preciso parar rapidamente e retornar o erro ao usuário. O errgroup faz isso automaticamente: você passa um contexto e, ao primeiro erro, o contexto é cancelado, e todas as goroutines que escutam esse contexto podem ser finalizadas precocemente.

Isso é especialmente útil em microsserviços, servidores web e utilitários de linha de comando, onde a velocidade de reação a erros é crucial. Diferente do gerenciamento manual com canais e select, o errgroup oferece uma API limpa e declarativa, difícil de usar incorretamente.

2. Instalação

O sync/errgroup não faz parte da biblioteca padrão do Go, mas é um submódulo de golang.org/x/sync. A instalação é feita com um único comando:

go get golang.org/x/sync/errgroup

Depois disso, você pode importar o pacote no seu código:

import "golang.org/x/sync/errgroup"

Certifique-se de ter o Go versão 1.13 ou superior (recomenda-se 1.18+ para suporte a generics, embora o errgroup não os utilize). Se você usa módulos (go.mod), o comando go get atualizará automaticamente o arquivo go.sum.

3. Início rápido — exemplo mínimo funcional

Abaixo está um exemplo simples que inicia três goroutines, cada uma retornando um erro se o número passado for negativo. Se pelo menos uma goroutine retornar um erro, errgroup.Wait() o retornará.

package main

import (
    "context"
    "fmt"
    "golang.org/x/sync/errgroup"
)

func main() {
    g, ctx := errgroup.WithContext(context.Background())

    numbers := []int{1, -2, 3}
    for _, n := range numbers {
        n := n // captura de variável
        g.Go(func() error {
            select {
            case <-ctx.Done():
                return ctx.Err()
            default:
            }
            if n < 0 {
                return fmt.Errorf("número negativo: %d", n)
            }
            fmt.Printf("Processado %d\n", n)
            return nil
        })
    }

    if err := g.Wait(); err != nil {
        fmt.Printf("Erro: %v\n", err)
    } else {
        fmt.Println("Todas as tarefas concluídas com sucesso")
    }
}

Saída: Processado 1, Processado 3, Erro: número negativo: -2. Observe que a goroutine com o número 3 pode não ter sido executada se o contexto tivesse sido cancelado antes de sua execução — isso demonstra o mecanismo de parada antecipada.

4. Métodos/funções principais

Abaixo estão todos os elementos-chave da API do pacote errgroup. Cada método vem com assinatura, descrição e um exemplo funcional.

4.1. WithContext

Assinatura: func Wi

Recommendations