Skip to content

Instantly share code, notes, and snippets.

@yael-castro
Last active August 5, 2023 21:34
Show Gist options
  • Save yael-castro/9b6586ced811305df051692fd30ff61a to your computer and use it in GitHub Desktop.
Save yael-castro/9b6586ced811305df051692fd30ff61a to your computer and use it in GitHub Desktop.
Stop n goroutines in case of any failure
// Package main
//
// - This is an example of how to stop several concurrent processes if an unexpected error occurs in one process.
// - This is a specific example of error management in multiple processes that can serve as a basis for solving other similar problems.
//
// Go Playground: https://go.dev/play/p/FrDs5m4fzWZ
//
package main
import (
"context"
"errors"
"math/rand"
"strconv"
"sync"
"time"
)
// timeout random timeout for the process function
var timeout = time.Duration(rand.Intn(1_500)) * time.Millisecond
// process simulates some process that will run concurrently
func process(ctx context.Context, index int) error {
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(time.Second): // Simulates process execution time
return nil
case <-time.After(timeout): // Simulates process error
return errors.New("an unexpected error occurs during the process " + strconv.Itoa(index) + " after " + timeout.String())
}
}
func main() {
ctx, cancel := context.WithCancel(context.TODO())
defer cancel() // This line ensures that the context is cancelled and the resources associated with it are free.
wg := sync.WaitGroup{}
errCh := make(chan error, 1) // The channel must have at least one space to avoid a deadlock.
for index := 0; index < 1_000; index++ {
wg.Add(1)
go func(index int) {
defer wg.Done()
if err := process(ctx, index); err != nil {
select {
case <-ctx.Done():
return
case errCh <- err:
cancel()
return
}
}
}(index) // Creating another index variable at each iteration avoids a data race condition.
}
wg.Wait()
close(errCh) // The channel must be closed to avoid a deadlock.
// Error management
if err := <-errCh; err != nil {
println("Error:", err.Error())
return
}
println("Done!")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment