Last active
October 17, 2018 06:25
-
-
Save whitekid/d289b0547cd467f5fe963f76557eb02e to your computer and use it in GitHub Desktop.
Stop multiple goroutine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// play at https://play.golang.org/p/lHRnRJHPheY | |
package main | |
import ( | |
"context" | |
"errors" | |
"log" | |
"sync" | |
"time" | |
) | |
type FN func(context.Context) error | |
func doSomething(ctx context.Context) error { | |
for i := 0; i < 3; i++ { | |
select { | |
case <-ctx.Done(): | |
return nil | |
default: | |
} | |
log.Print("doSomething...") | |
time.Sleep(time.Second) | |
} | |
return nil | |
} | |
func doSomethingError(ctx context.Context) error { | |
return errors.New("Error on doSomething") | |
} | |
func run(fns []FN) error { | |
wg := sync.WaitGroup{} | |
ctxs := make([]struct { | |
ctx context.Context | |
cancel context.CancelFunc | |
}, len(fns)) | |
stop := func() { | |
for _, ctx := range ctxs { | |
ctx.cancel() | |
} | |
} | |
var retError error | |
for i, fn := range fns { | |
wg.Add(1) | |
ctx, cancel := context.WithCancel(context.Background()) | |
ctxs[i].ctx = ctx | |
ctxs[i].cancel = cancel | |
go func(ctx context.Context, fn FN) { | |
defer wg.Done() | |
if err := fn(ctx); err != nil { | |
// if error occurred then stop all go routines.. | |
log.Print(err) | |
retError = err | |
stop() | |
} | |
}(ctx, fn) | |
} | |
// give some time to stop | |
wg.Wait() | |
return retError | |
} | |
func main() { | |
for _, test := range []struct { | |
fns []FN | |
hasError bool | |
}{ | |
{ | |
fns: []FN{ | |
doSomething, | |
doSomething, | |
}, | |
hasError: false, | |
}, | |
{ | |
fns: []FN{ | |
doSomething, | |
doSomethingError, | |
}, | |
hasError: true, | |
}, | |
} { | |
err := run(test.fns) | |
if test.hasError { | |
if err == nil { | |
log.Printf("ERR: error expected but nil") | |
} | |
} else { | |
if err != nil { | |
log.Printf("ERR: no error expected but err: %s", err) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment