github.com/huiliang/nomad@v0.2.1-0.20151124023127-7a8b664699ff/nomad/util.go (about) 1 package nomad 2 3 import ( 4 "fmt" 5 "math/rand" 6 "net" 7 "os" 8 "path/filepath" 9 "runtime" 10 "strconv" 11 "time" 12 13 "github.com/hashicorp/serf/serf" 14 ) 15 16 // ensurePath is used to make sure a path exists 17 func ensurePath(path string, dir bool) error { 18 if !dir { 19 path = filepath.Dir(path) 20 } 21 return os.MkdirAll(path, 0755) 22 } 23 24 // RuntimeStats is used to return various runtime information 25 func RuntimeStats() map[string]string { 26 return map[string]string{ 27 "kernel.name": runtime.GOOS, 28 "arch": runtime.GOARCH, 29 "version": runtime.Version(), 30 "max_procs": strconv.FormatInt(int64(runtime.GOMAXPROCS(0)), 10), 31 "goroutines": strconv.FormatInt(int64(runtime.NumGoroutine()), 10), 32 "cpu_count": strconv.FormatInt(int64(runtime.NumCPU()), 10), 33 } 34 } 35 36 // serverParts is used to return the parts of a server role 37 type serverParts struct { 38 Name string 39 Region string 40 Datacenter string 41 Port int 42 Bootstrap bool 43 Expect int 44 Version int 45 Addr net.Addr 46 } 47 48 func (s *serverParts) String() string { 49 return fmt.Sprintf("%s (Addr: %s) (DC: %s)", 50 s.Name, s.Addr, s.Datacenter) 51 } 52 53 // Returns if a member is a Nomad server. Returns a boolean, 54 // and a struct with the various important components 55 func isNomadServer(m serf.Member) (bool, *serverParts) { 56 if m.Tags["role"] != "nomad" { 57 return false, nil 58 } 59 60 region := m.Tags["region"] 61 datacenter := m.Tags["dc"] 62 _, bootstrap := m.Tags["bootstrap"] 63 64 expect := 0 65 expect_str, ok := m.Tags["expect"] 66 var err error 67 if ok { 68 expect, err = strconv.Atoi(expect_str) 69 if err != nil { 70 return false, nil 71 } 72 } 73 74 port_str := m.Tags["port"] 75 port, err := strconv.Atoi(port_str) 76 if err != nil { 77 return false, nil 78 } 79 80 vsn_str := m.Tags["vsn"] 81 vsn, err := strconv.Atoi(vsn_str) 82 if err != nil { 83 return false, nil 84 } 85 86 addr := &net.TCPAddr{IP: m.Addr, Port: port} 87 parts := &serverParts{ 88 Name: m.Name, 89 Region: region, 90 Datacenter: datacenter, 91 Port: port, 92 Bootstrap: bootstrap, 93 Expect: expect, 94 Addr: addr, 95 Version: vsn, 96 } 97 return true, parts 98 } 99 100 // Returns a random stagger interval between 0 and the duration 101 func randomStagger(intv time.Duration) time.Duration { 102 return time.Duration(uint64(rand.Int63()) % uint64(intv)) 103 } 104 105 // shuffleStrings randomly shuffles the list of strings 106 func shuffleStrings(list []string) { 107 for i := range list { 108 j := rand.Intn(i + 1) 109 list[i], list[j] = list[j], list[i] 110 } 111 } 112 113 // maxUint64 returns the maximum value 114 func maxUint64(a, b uint64) uint64 { 115 if a >= b { 116 return a 117 } 118 return b 119 } 120 121 // rateScaledInterval is used to choose an interval to perform an action in order 122 // to target an aggregate number of actions per second across the whole cluster. 123 func rateScaledInterval(rate float64, min time.Duration, n int) time.Duration { 124 interval := time.Duration(float64(time.Second) * float64(n) / rate) 125 if interval < min { 126 return min 127 } 128 return interval 129 }