| // +build OMIT |
| |
| package main |
| |
| import ( |
| "fmt" |
| "math/rand" |
| "time" |
| ) |
| |
| type Result string |
| type Search func(query string) Result |
| |
| var ( |
| Web1 = fakeSearch("web1") |
| Web2 = fakeSearch("web2") |
| Image1 = fakeSearch("image1") |
| Image2 = fakeSearch("image2") |
| Video1 = fakeSearch("video1") |
| Video2 = fakeSearch("video2") |
| ) |
| |
| func Google(query string) (results []Result) { |
| // START OMIT |
| c := make(chan Result, 3) |
| go func() { c <- First(query, Web1, Web2) }() // HL |
| go func() { c <- First(query, Image1, Image2) }() // HL |
| go func() { c <- First(query, Video1, Video2) }() // HL |
| 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 |
| // STOP OMIT |
| } |
| |
| func First(query string, replicas ...Search) Result { |
| c := make(chan Result, len(replicas)) |
| searchReplica := func(i int) { |
| c <- replicas[i](query) |
| } |
| for i := range replicas { |
| go searchReplica(i) |
| } |
| return <-c |
| } |
| |
| 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)) |
| } |
| } |
| |
| func init() { |
| rand.Seed(time.Now().UnixNano()) |
| } |
| |
| func main() { |
| start := time.Now() |
| results := Google("golang") |
| elapsed := time.Since(start) |
| fmt.Println(results) |
| fmt.Println(elapsed) |
| } |