Skip to content

Instantly share code, notes, and snippets.

@mobleyc
Created October 5, 2015 01:10
Show Gist options
  • Save mobleyc/21e1bd3083357f25c94d to your computer and use it in GitHub Desktop.
Save mobleyc/21e1bd3083357f25c94d to your computer and use it in GitHub Desktop.
Go Concurrency Patterns
package main
import (
"fmt"
"math/rand"
"time"
)
// Examples from https://talks.golang.org/2012/concurrency.slide, starting at slide 42, https://talks.golang.org/2012/concurrency.slide#42
var (
Web = fakeSearch("web")
Image = fakeSearch("image")
Video = fakeSearch("video")
)
type Result string
type Search func(query string) Result
func fakeSearch(kind string) Search {
return func(query string) Result {
wait := time.Duration(rand.Intn(100)) * time.Millisecond
time.Sleep(wait)
return Result(fmt.Sprintf("%s result for %q, took %v\n", kind, query, wait))
}
}
//Google Search 1.0 - Serial invocation
func Google1(query string) (results []Result) {
results = append(results, Web(query))
results = append(results, Image(query))
results = append(results, Video(query))
return
}
//Google Search 2.0 - Concurrent invocation, wait for all results
func Google2(query string) (results []Result) {
c := make(chan Result)
go func() { c <- Web(query) }()
go func() { c <- Image(query) }()
go func() { c <- Video(query) }()
for i := 0; i < 3; i++ {
result := <-c
results = append(results, result)
}
return
}
//Google Search 2.1 - Don't wait on slow servers
func Google21(query string, timeout time.Duration) (results []Result) {
c := make(chan Result)
go func() { c <- Web(query) }()
go func() { c <- Image(query) }()
go func() { c <- Video(query) }()
t := time.After(timeout)
for i := 0; i < 3; i++ {
select {
case result := <-c:
results = append(results, result)
case <-t:
fmt.Println("timed out")
return
}
}
return
}
func main() {
rand.Seed(time.Now().UnixNano())
start := time.Now()
//results := Google1("golang")
//results := Google2("golang")
results := Google21("golang", 80*time.Millisecond)
elapsed := time.Since(start)
fmt.Println(results)
fmt.Println(elapsed)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment