package main import ( "fmt" "math/rand" "sync" "time" ) const N = 1000 func CallMe() error { n := rand.Intn(N) if n == 888 { return fmt.Errorf("lucky: %d", n) } <-time.After(time.Duration(n) * time.Millisecond) fmt.Printf("Waited: %d\n", n) return nil } func main() { // run 1000 goroutine for CallMe, program exit after all goroutines exit. var wg sync.WaitGroup for i := 0; i < 1000; i++ { wg.Add(1) go func(){ CallMe() wg.Done() } } wg.Wait() } // 2. follow-up: when CallMe hit the lucky number 888, it returns an error immediately. // we hope the program can gracefully exit when any of the goroutine returns an error, // without waiting. You can change CallMe function.