1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
   | package main
  import ( 	"fmt" 	"math/rand" 	"time" )
 
 
 
 
  type Result string
  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)) 	} }
  var ( 	Web1   = fakeSearch("web1") 	Web2   = fakeSearch("web2") 	Image1 = fakeSearch("image1") 	Image2 = fakeSearch("image2") 	Video1 = fakeSearch("video1") 	Video2 = fakeSearch("video2") )
  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, 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 		} 	} 	return }
  func main() { 	start := time.Now() 	results := Google("golang") 	elapsed := time.Since(start) 	fmt.Println(results) 	fmt.Println(elapsed) }
   |