Skip to content

Instantly share code, notes, and snippets.

@wrfly
Last active October 23, 2018 08:57
Show Gist options
  • Save wrfly/1dc4b23763d0e06ef4bd1a6855cda6b0 to your computer and use it in GitHub Desktop.
Save wrfly/1dc4b23763d0e06ef4bd1a6855cda6b0 to your computer and use it in GitHub Desktop.
error selection
package main
import (
"fmt"
"time"
)
type e struct{}
func chanErr(produceErr bool, d time.Duration, noErrChan chan e) chan e {
c := make(chan e)
go func() {
time.Sleep(d)
if !produceErr {
noErrChan <- e{}
} else {
close(c)
}
}()
return c
}
func println(msg string) {
fmt.Printf("[%s] %s\n",
time.Now().Format("2006-01-02 15:04:05.999999999"),
msg)
}
func allPassed(checkNum int) (finishChan, noErrChan chan e) {
noErrChan = make(chan e, checkNum)
finishChan = make(chan e)
go func() {
for {
select {
case <-noErrChan:
checkNum--
if checkNum == 0 {
close(finishChan)
return
}
case <-finishChan:
return
}
}
}()
return
}
func main() {
println("start")
var produceErr bool
// produceErr = true
timeOut := time.NewTimer(time.Second * 2)
defer timeOut.Stop()
finishChan, noErrChan := allPassed(4)
errA := chanErr(produceErr, time.Second, noErrChan)
errB := chanErr(produceErr, time.Second/2, noErrChan)
errC := chanErr(produceErr, time.Second/3, noErrChan)
errD := chanErr(produceErr, time.Second/4, noErrChan)
var passed bool
select {
case <-errA:
println("got error A")
case <-errB:
println("got error B")
case <-errC:
println("got error C")
case <-errD:
println("got error D")
case <-finishChan:
passed = true
println("all passed")
case <-timeOut.C:
println("time out!")
}
if passed {
close(finishChan)
}
return
}
@wrfly
Copy link
Author

wrfly commented Oct 22, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment