new(conc): Finished.
authorsgf <sgf.dma@gmail.com>
Fri, 9 Sep 2022 13:49:28 +0000 (16:49 +0300)
committersgf <sgf.dma@gmail.com>
Fri, 9 Sep 2022 13:49:28 +0000 (16:49 +0300)
go-concurrency-patterns/conc2.go

index 20434c4..dd1df46 100644 (file)
@@ -11,6 +11,10 @@ var (
     Web = fakeSearch("web")
     Image = fakeSearch("image")
     Video = fakeSearch("video")
+
+    Web2 = fakeSearch("web2")
+    Image2 = fakeSearch("image2")
+    Video2 = fakeSearch("video2")
 )
 
 type Search func(query string) Result
@@ -19,6 +23,7 @@ type Result string
 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))
     }
@@ -63,10 +68,44 @@ func Google21(query string) (results []Result) {
     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)