Skip to content

Instantly share code, notes, and snippets.

@yinyin
Last active October 15, 2017 12:19
Show Gist options
  • Save yinyin/1b5e02a3d343a58d34eedaa39aef8965 to your computer and use it in GitHub Desktop.
Save yinyin/1b5e02a3d343a58d34eedaa39aef8965 to your computer and use it in GitHub Desktop.
Go channel experiment: see if what would result in select under various channel conditions.
package main
/*
See if what would result in select under various channel conditions.
Outputs:
- On mode = 1 (worker-1): "Got error: error at 2017-10-15 19:33:00.687713221 ... (ok: true)"
- On mode = 2 (worker-2): "Got error: <nil> (ok: true)"
- On mode = 3 (worker-2): "Got error: <nil> (ok: false)"
- On mode = -9 (timeout): "Have context done."
*/
import (
"context"
"fmt"
"os"
"strconv"
"time"
)
func channelWorker1(d time.Duration, ch chan<- error) {
time.Sleep(d)
err := fmt.Errorf("error at %v", time.Now())
ch <- err
}
func channelWorker2(d time.Duration, ch chan<- error) {
time.Sleep(d)
ch <- nil
}
func channelWorker3(d time.Duration, ch chan<- error) {
time.Sleep(d)
close(ch)
}
func getWaitSeconds(mode int) (worker1, worker2, worker3, timeout time.Duration) {
if 1 == mode {
return 1, 3, 5, 7
} else if 2 == mode {
return 3, 1, 5, 7
} else if 3 == mode {
return 3, 5, 1, 7
}
return 9, 9, 9, 1
}
func main() {
mode, _ := strconv.Atoi(os.Args[1])
worker1Idle, worker2Idle, worker3Idle, timeoutIdle := getWaitSeconds(mode)
errChannel := make(chan error)
go channelWorker1(time.Second*worker1Idle, errChannel)
go channelWorker2(time.Second*worker2Idle, errChannel)
go channelWorker3(time.Second*worker3Idle, errChannel)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*timeoutIdle)
defer cancel()
select {
case err, ok := <-errChannel:
fmt.Printf("[mode: %v] Got error: %v (ok: %v)\n", mode, err, ok)
case <-ctx.Done():
fmt.Printf("[mode: %v] Have context done.\n", mode)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment