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
Também na biblioteca
Biblioteca Padrão PHP: visão geral completa de funções e classes
Symfony/EventDispatcher para PHP: guia completo com exemplos
Processamento JSON em Rust: serde_json, simd-json, json5 e outras bibliotecas
Aprendizado de Máquina em JavaScript: bibliotecas para Node.js — visão geral e exemplos