Web = fakeSearch("web")
Image = fakeSearch("image")
Video = fakeSearch("video")
+
+ Web2 = fakeSearch("web2")
+ Image2 = fakeSearch("image2")
+ Video2 = fakeSearch("video2")
)
type Search func(query string) Result
func fakeSearch(kind string) Search {
return func(query string) Result {
r := rand.Intn(100)
+ fmt.Printf("%s sleep for %v\n", kind, r)
time.Sleep(time.Duration(r) * time.Millisecond)
return Result(fmt.Sprintf("%s result for %q (takes %v)\n", kind, query, r))
}
return
}
+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 tryReplica(query string) []Result {
+ results := make([]Result, 1)
+ results[0] = First(query, fakeSearch("replica 1"), fakeSearch("replica 2"))
+ return results
+}
+
+func Google30(query string) (results []Result) {
+ c := make(chan Result)
+ go func() { c <- First(query, Web, Web2) } ()
+ go func() { c <- First(query, Image, Image2) } ()
+ go func() { c <- First(query, Video, 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
+ }
+ }
+ return
+}
+
func main() {
rand.Seed(time.Now().UnixNano())
start := time.Now()
- results := Google21("golang")
+ results := Google30("golang")
elapsed := time.Since(start)
fmt.Println(results)
fmt.Println(elapsed)