--- /dev/null
+
+package main
+
+import (
+ "fmt"
+ "time"
+ "math/rand"
+)
+
+var (
+ Web = fakeSearch("web")
+ Image = fakeSearch("image")
+ Video = fakeSearch("video")
+)
+
+type Search func(query string) Result
+type Result string
+
+func fakeSearch(kind string) Search {
+ return func(query string) Result {
+ r := rand.Intn(100)
+ time.Sleep(time.Duration(r) * time.Millisecond)
+ return Result(fmt.Sprintf("%s result for %q (takes %v)\n", kind, query, r))
+ }
+}
+
+func Google10(query string) (results []Result) {
+ results = append(results, Web(query))
+ results = append(results, Image(query))
+ results = append(results, Video(query))
+ return
+}
+
+func Google20(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
+}
+
+func Google21(query string) (results []Result) {
+ c := make(chan Result)
+ go func() { c <- Web(query) } ()
+ go func() { c <- Image(query) } ()
+ go func() { c <- Video(query) } ()
+
+ 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")
+ elapsed := time.Since(start)
+ fmt.Println(results)
+ fmt.Println(elapsed)
+}
+