Terminaison idiomatique de Goroutine et gestion des erreurs : une étude de cas
Dans Go, la gestion de la terminaison de Goroutine est souvent un défi pour les développeurs. Un problème courant consiste à assurer un nettoyage approprié des goroutines lorsqu'une erreur se produit. Cet article présente une solution élégante et idiomatique à ce problème en utilisant le regroupement d'erreurs.
Considérez l'exemple suivant :
package main import ( "sync" "time" ) func fetchAll() error { wg := sync.WaitGroup{} errs := make(chan error) // run all the http requests in parallel for i := 0; i < 4; i++ { wg.Add(1) go func(i int) { defer wg.Done() // pretend this does an http request and returns an error time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond) errs <- fmt.Errorf("goroutine %d's error returned", i) }(i) } // wait until all the fetches are done and close the error // channel so the loop below terminates go func() { wg.Wait() close(errs) }() // return the first error for err := range errs { if err != nil { return err } } return nil }
Cette implémentation présente un défaut critique : elle laisse fuir les goroutines. Le correctif consiste à utiliser un groupe d'erreurs :
package main import ( "context" "fmt" "math/rand" "time" "golang.org/x/sync/errgroup" ) func fetchAll(ctx context.Context) error { errs, ctx := errgroup.WithContext(ctx) // run all the http requests in parallel for i := 0; i < 4; i++ { errs.Go(func() error { // pretend this does an http request and returns an error time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond) return fmt.Errorf("error in go routine, bailing") }) } // Wait for completion and return the first error (if any) return errs.Wait() }
Un groupe d'erreurs attend automatiquement que toutes les goroutines se terminent avec succès ou annule celles restantes en cas d'erreur. Dans le cas ci-dessus, la première goroutine qui rencontre une erreur déclenche l'annulation de toutes les autres et l'erreur est propagée à l'appelant. L'utilisation du contexte garantit une terminaison gracieuse lorsque le contexte environnant est annulé.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!