package main import ( "fmt" "math/rand" "time" ) type Search func(query string) Result type Result struct { Goodies string } 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", kind, query)} } } 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 } func Google(query string) (results []Result) { c := make(chan Result) go func() { c <- First(query, fakeSearch("web 1"), fakeSearch("web 2")) }() go func() { c <- First(query, fakeSearch("vid 1"), fakeSearch("vid 2")) }() go func() { c <- First(query, fakeSearch("img 1"), fakeSearch("img 2")) }() 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 } } return }