Skip to content

Instantly share code, notes, and snippets.

@bbirec
Created September 19, 2017 14:20
Show Gist options
  • Save bbirec/183f01a978d2ff3a36b0f21c972edb30 to your computer and use it in GitHub Desktop.
Save bbirec/183f01a978d2ff3a36b0f21c972edb30 to your computer and use it in GitHub Desktop.
// Channels-driven concurrency with Go
// Code examples from Rob Pike's talk on Google I/O 2012:
// http://www.youtube.com/watch?v=f6kdp27TYZs&feature=youtu.be
//
// Concurrency is the key to designing high performance network services.
// Go's concurrency primitives (goroutines and channels) provide a simple and efficient means
// of expressing concurrent execution. In this talk we see how tricky concurrency
// problems can be solved gracefully with simple Go code.
// (7) Fake Google search
var (
Web = fakeSearch("web")
Image = fakeSearch("image")
Video = fakeSearch("video")
)
type Search func(query string) Result
func fakeSearch(kind string) Search {
return func(query string) Result {
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
return Result(fmt.Sprintf("%s result for %q\n", kind, query))
}
}
// Replication in order to avoid timeouts
func First(query string, replicas ...Search) Result {
c := make(chan Result)
searchReplica := func(i, int) { c <- replicas[i](query) }
for i := range replicas {
go searchReplica(i)
}
return <-c
}
// Main search function
func Google(query sting) (results []Result) {
c := make(chan Result)
go func() { c <- First(query, Web1, Web2) }()
go func() { c <- First(query, Image1, Image2) }()
go func() { c <- First(query, Video1, Video2) }()
timeout := time.After(80 * time.Millisecond)
for i := 0; i < 3; i++ {
select {
case result := <-c:
results = append(results, result)
case <-timeout:
fmt.Println("timed out.")
return
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment