LEFT | RIGHT |
(no file at all) | |
| 1 package main |
| 2 |
| 3 import ( |
| 4 "fmt" |
| 5 "math/rand" |
| 6 "time" |
| 7 ) |
| 8 |
| 9 func lookup() { |
| 10 done := make(chan bool, len(worklist)) |
| 11 |
| 12 for _, w := range worklist { |
| 13 go func(w *Work) { |
| 14 w.addrs, w.err = LookupHost(w.host) |
| 15 done <- true |
| 16 }(w) |
| 17 } |
| 18 |
| 19 for i := 0; i < len(worklist); i++ { |
| 20 <-done |
| 21 } |
| 22 } |
| 23 |
| 24 func main() { |
| 25 rand.Seed(time.Now().UnixNano()) |
| 26 |
| 27 t0 := time.Now() |
| 28 lookup() |
| 29 |
| 30 fmt.Printf("\n") |
| 31 for _, w := range worklist { |
| 32 if w.err != nil { |
| 33 fmt.Printf("%s: error: %v\n", w.host, w.err) |
| 34 continue |
| 35 } |
| 36 fmt.Printf("%s: %v\n", w.host, w.addrs) |
| 37 } |
| 38 fmt.Printf("total lookup time: %.3f seconds\n", time.Since(t0).Seconds()
) |
| 39 } |
| 40 |
| 41 var worklist = []*Work{ |
| 42 {host: "fast.com"}, |
| 43 {host: "slow.com"}, |
| 44 {host: "fast.missing.com"}, |
| 45 {host: "slow.missing.com"}, |
| 46 } |
| 47 |
| 48 type Work struct { |
| 49 host string |
| 50 addrs []string |
| 51 err error |
| 52 } |
| 53 |
| 54 func LookupHost(name string) (addrs []string, err error) { |
| 55 t0 := time.Now() |
| 56 defer func() { |
| 57 fmt.Printf("lookup %s: %.3f seconds\n", name, time.Since(t0).Sec
onds()) |
| 58 }() |
| 59 h := hosts[name] |
| 60 if h == nil { |
| 61 h = failure |
| 62 } |
| 63 return h(name) |
| 64 } |
| 65 |
| 66 type resolver func(string) ([]string, error) |
| 67 |
| 68 var hosts = map[string]resolver{ |
| 69 "fast.com": delay(10*time.Millisecond, fixedAddrs("10.0.0.1")), |
| 70 "slow.com": delay(2*time.Second, fixedAddrs("10.0.0.4")), |
| 71 "fast.missing.com": delay(10*time.Millisecond, failure), |
| 72 "slow.missing.com": delay(2*time.Second, failure), |
| 73 } |
| 74 |
| 75 func fixedAddrs(addrs ...string) resolver { |
| 76 return func(string) ([]string, error) { |
| 77 return addrs, nil |
| 78 } |
| 79 } |
| 80 |
| 81 func delay(d time.Duration, f resolver) resolver { |
| 82 return func(name string) ([]string, error) { |
| 83 time.Sleep(d/2 + time.Duration(rand.Int63n(int64(d/2)))) |
| 84 return f(name) |
| 85 } |
| 86 } |
| 87 |
| 88 func failure(name string) ([]string, error) { |
| 89 return nil, fmt.Errorf("unknown host %v", name) |
| 90 } |
LEFT | RIGHT |