Generator: function that returns a channel
package main
import (
"fmt"
"math/rand"
"time"
)
func boring (msg string ) <- chan string {
c := make (chan string )
go func () {
for i := 0 ; ; i ++ {
c <- fmt .Sprintf ("%s %d" , msg , i )
time .Sleep (time .Duration (rand .Intn (1e3 )) * time .Millisecond )
}
}()
return c
}
func main () {
c := boring ("boring!" )
for i := 0 ; i < 5 ; i ++ {
fmt .Printf ("You say: %q\n " , <- c )
}
fmt .Println ("You're boring; I'm leaving." )
}
"Go Concurrency Patterns"
Multiplexing / Fan-in function
package main
import (
"fmt"
"math/rand"
"time"
)
func boring (msg string ) <- chan string {
c := make (chan string )
go func () {
for i := 0 ; ; i ++ {
c <- fmt .Sprintf ("%s %d" , msg , i )
time .Sleep (time .Duration (rand .Intn (1e3 )) * time .Millisecond )
}
}()
return c
}
func fanIn (inputs ... <- chan string ) <- chan string {
c := make (chan string )
for _ , input := range inputs {
in := input
go func () {
for {
c <- <- in
}
}()
}
return c
}
func main () {
c := fanIn (boring ("Joe" ), boring ("Ann" ))
for i := 0 ; i < 10 ; i ++ {
fmt .Println (<- c )
}
fmt .Println ("You're boring: I'm leaving." )
}
"Go Concurrency Patterns"
Multiplexing using select
package main
import (
"fmt"
"math/rand"
"time"
)
func boring (msg string ) <- chan string {
c := make (chan string )
go func () {
for i := 0 ; ; i ++ {
c <- fmt .Sprintf ("%s %d" , msg , i )
time .Sleep (time .Duration (rand .Intn (1e3 )) * time .Millisecond )
}
}()
return c
}
func fanIn (input1 , input2 <- chan string ) <- chan string {
c := make (chan string )
go func () {
for {
select {
case c <- <- input1 :
case c <- <- input2 :
}
}
}()
return c
}
func main () {
c := fanIn (boring ("Joe" ), boring ("Ann" ))
for i := 0 ; i < 10 ; i ++ {
fmt .Println (<- c )
}
fmt .Println ("You're boring: I'm leaving." )
}
"Go Concurrency Patterns"
package main
import (
"fmt"
"math/rand"
"time"
)
func boring (msg string ) <- chan string {
c := make (chan string )
go func () {
for i := 0 ; ; i ++ {
c <- fmt .Sprintf ("%s %d" , msg , i )
time .Sleep (time .Duration (rand .Intn (1e3 )) * time .Millisecond )
}
}()
return c
}
func main () {
c := boring ("Joe" )
for {
select {
case s := <- c :
fmt .Println (s )
case <- time .After (900 * time .Millisecond ):
fmt .Println ("You're too slow." )
return
}
}
}
"Go Concurrency Patterns"
Timeout for whole conversation using select
package main
import (
"fmt"
"math/rand"
"time"
)
func boring (msg string ) <- chan string {
c := make (chan string )
go func () {
for i := 0 ; ; i ++ {
c <- fmt .Sprintf ("%s %d" , msg , i )
time .Sleep (time .Duration (rand .Intn (1e3 )) * time .Millisecond )
}
}()
return c
}
func main () {
c := boring ("Joe" )
timeout := time .After (5 * time .Second )
for {
select {
case s := <- c :
fmt .Println (s )
case <- timeout :
fmt .Println ("You talk too much." )
return
}
}
}
"Go Concurrency Patterns"
package main
import (
"fmt"
"math/rand"
"time"
)
func boring (msg string , quit <- chan struct {}) <- chan string {
c := make (chan string )
go func () {
for i := 0 ; ; i ++ {
select {
case c <- fmt .Sprintf ("%s %d" , msg , i ):
case <- quit :
return
}
time .Sleep (time .Duration (rand .Intn (1e3 )) * time .Millisecond )
}
}()
return c
}
func main () {
quit := make (chan struct {})
c := boring ("Joe" , quit )
for i := 0 ; i < 10 ; i ++ {
fmt .Println (<- c )
}
quit <- struct {}{}
}
"Go Concurrency Patterns"
package main
import (
"fmt"
"math/rand"
"time"
)
func boring (msg string , quit chan string ) <- chan string {
c := make (chan string )
go func () {
for i := 0 ; ; i ++ {
select {
case c <- fmt .Sprintf ("%s %d" , msg , i ):
case <- quit :
// Do something
quit <- "See you!"
return
}
time .Sleep (time .Duration (rand .Intn (1e3 )) * time .Millisecond )
}
}()
return c
}
func main () {
quit := make (chan string )
c := boring ("Joe" , quit )
for i := 0 ; i < 10 ; i ++ {
fmt .Println (<- c )
}
quit <- "Bye!"
fmt .Printf ("Joe says: %q\n " , <- quit )
}