Când o cerere HTTP trebuie să execute mai multe operațiuni paralele (de exemplu interogarea simultană a unui profil de utilizator, a listei de comenzi și a recomandărilor din baze de date separate), utilizarea clasică a lui sync.WaitGroup este insuficientă, deoarece nu oferă un mod nativ de a propaga erorile și de a anula celelalte operațiuni dacă una dintre ele eșuează. Pachetul errgroup rezolvă exact această problemă: coordonează un grup de goroutine-uri, captează prima eroare apărută și anulează automat contextul pentru restul sarcinilor.
package main
import (
"context"
"fmt"
"net/http"
"golang.org/x/sync/errgroup"
)
func verificaServicii(ctx context.Context, urls []string) error {
// 1. Creăm un errgroup legat de un context derivat:
g, ctx := errgroup.WithContext(ctx)
// (Opțional): Limităm numărul maxim de goroutine-uri concurente:
g.SetLimit(3)
for _, u := range urls {
url := u // Captură variabilă de buclă
g.Go(func() error {
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("esec la interogarea %s: %w", url, err)
}
defer resp.Body.Close()
fmt.Printf("Succes: %s -> Status %d
", url, resp.StatusCode)
return nil
})
}
// 2. Așteptăm finalizarea tuturor goroutine-urilor:
// Returnează prima eroare întâlnită; celelalte goroutine-uri active primesc ctx.Done()!
return g.Wait()
}