Skip to content

Instantly share code, notes, and snippets.

@clarkenciel
Created October 18, 2018 22:20
Show Gist options
  • Save clarkenciel/fe1e66c1f20d33aa8f75e64e389008d5 to your computer and use it in GitHub Desktop.
Save clarkenciel/fe1e66c1f20d33aa8f75e64e389008d5 to your computer and use it in GitHub Desktop.
playing around with passing messages in a non-blocking way with go
package main
import (
"fmt"
"time"
"sync"
"math/rand"
)
func main() {
ones := make(chan int)
tens := make(chan int)
strs := make(chan string)
go func() {
defer close(ones)
var wg sync.WaitGroup
for _, x := range []int{1, 2, 3, 4, 5, 6} {
wg.Add(1)
go func(x int) {
defer wg.Done()
fmt.Printf("Sending ONE: %d\n", x)
sleep()
ones <- x
fmt.Printf("Sent ONE: %d\n", x)
}(x)
}
wg.Wait()
}()
go func() {
defer close(tens)
var (
done bool
ts []int
t int
)
for !done {
select {
case o, ok := <- ones:
done = !ok
go func(o int) {
fmt.Printf("\tReceived ONE: %d\n", o)
ts = append(ts, o * 10)
}(o)
default:
if len(ts) > 0 {
t, ts = ts[0], ts[1:]
go func(t int) {
fmt.Printf("\tSending TEN: %d\n", t)
sleep()
tens <- t
fmt.Printf("\tSent TEN: %d\n", t)
}(t)
}
}
}
}()
go func() {
defer close(strs)
var (
done bool
ses []string
s string
)
for !done {
select {
case t, ok := <- tens:
done = !ok
go func(t int) {
fmt.Printf("\t\tReceived TEN: %d\n", t)
ses = append(ses, fmt.Sprint(t))
}(t)
default:
if len(ses) > 0 {
s, ses = ses[0], ses[1:]
go func(s string) {
fmt.Printf("\t\tSending STR: %s\n", s)
sleep()
strs <- s
fmt.Printf("\t\tSent STR: %s\n", s)
}(s)
}
}
}
}()
for s := range strs {
fmt.Printf("\t\t\tReceived STR: %s\n", s)
}
}
func sleep() {
time.Sleep(time.Duration(rand.Float64() * float64(rand.Intn(1000))) * time.Millisecond)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment