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