github.com/alpe/etcd@v0.1.2-0.20130915230056-09f31af88aeb/util.go (about) 1 package main 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "log" 8 "net" 9 "net/http" 10 "net/url" 11 "os" 12 "os/signal" 13 "runtime/pprof" 14 "strconv" 15 "time" 16 17 "github.com/coreos/etcd/web" 18 ) 19 20 //-------------------------------------- 21 // etcd http Helper 22 //-------------------------------------- 23 24 // Convert string duration to time format 25 func durationToExpireTime(strDuration string) (time.Time, error) { 26 if strDuration != "" { 27 duration, err := strconv.Atoi(strDuration) 28 29 if err != nil { 30 return time.Unix(0, 0), err 31 } 32 return time.Now().Add(time.Second * (time.Duration)(duration)), nil 33 34 } else { 35 return time.Unix(0, 0), nil 36 } 37 } 38 39 //-------------------------------------- 40 // Web Helper 41 //-------------------------------------- 42 var storeMsg chan string 43 44 // Help to send msg from store to webHub 45 func webHelper() { 46 storeMsg = make(chan string) 47 etcdStore.SetMessager(storeMsg) 48 for { 49 // transfer the new msg to webHub 50 web.Hub().Send(<-storeMsg) 51 } 52 } 53 54 // startWebInterface starts web interface if webURL is not empty 55 func startWebInterface() { 56 if argInfo.WebURL != "" { 57 // start web 58 go webHelper() 59 go web.Start(r.Server, argInfo.WebURL) 60 } 61 } 62 63 //-------------------------------------- 64 // HTTP Utilities 65 //-------------------------------------- 66 67 func decodeJsonRequest(req *http.Request, data interface{}) error { 68 decoder := json.NewDecoder(req.Body) 69 if err := decoder.Decode(&data); err != nil && err != io.EOF { 70 warnf("Malformed json request: %v", err) 71 return fmt.Errorf("Malformed json request: %v", err) 72 } 73 return nil 74 } 75 76 func encodeJsonResponse(w http.ResponseWriter, status int, data interface{}) { 77 w.Header().Set("Content-Type", "application/json") 78 w.WriteHeader(status) 79 80 if data != nil { 81 encoder := json.NewEncoder(w) 82 encoder.Encode(data) 83 } 84 } 85 86 // sanitizeURL will cleanup a host string in the format hostname:port and 87 // attach a schema. 88 func sanitizeURL(host string, defaultScheme string) string { 89 // Blank URLs are fine input, just return it 90 if len(host) == 0 { 91 return host 92 } 93 94 p, err := url.Parse(host) 95 if err != nil { 96 fatal(err) 97 } 98 99 // Make sure the host is in Host:Port format 100 _, _, err = net.SplitHostPort(host) 101 if err != nil { 102 fatal(err) 103 } 104 105 p = &url.URL{Host: host, Scheme: defaultScheme} 106 107 return p.String() 108 } 109 110 // sanitizeListenHost cleans up the ListenHost parameter and appends a port 111 // if necessary based on the advertised port. 112 func sanitizeListenHost(listen string, advertised string) string { 113 aurl, err := url.Parse(advertised) 114 if err != nil { 115 fatal(err) 116 } 117 118 ahost, aport, err := net.SplitHostPort(aurl.Host) 119 if err != nil { 120 fatal(err) 121 } 122 123 // If the listen host isn't set use the advertised host 124 if listen == "" { 125 listen = ahost 126 } 127 128 return net.JoinHostPort(listen, aport) 129 } 130 131 func check(err error) { 132 if err != nil { 133 fatal(err) 134 } 135 } 136 137 //-------------------------------------- 138 // Log 139 //-------------------------------------- 140 141 var logger *log.Logger 142 143 func init() { 144 logger = log.New(os.Stdout, "[etcd] ", log.Lmicroseconds) 145 } 146 147 func infof(msg string, v ...interface{}) { 148 logger.Printf("INFO "+msg+"\n", v...) 149 } 150 151 func debugf(msg string, v ...interface{}) { 152 if verbose { 153 logger.Printf("DEBUG "+msg+"\n", v...) 154 } 155 } 156 157 func debug(v ...interface{}) { 158 if verbose { 159 logger.Println("DEBUG " + fmt.Sprint(v...)) 160 } 161 } 162 163 func warnf(msg string, v ...interface{}) { 164 logger.Printf("WARN "+msg+"\n", v...) 165 } 166 167 func warn(v ...interface{}) { 168 logger.Println("WARN " + fmt.Sprint(v...)) 169 } 170 171 func fatalf(msg string, v ...interface{}) { 172 logger.Printf("FATAL "+msg+"\n", v...) 173 os.Exit(1) 174 } 175 176 func fatal(v ...interface{}) { 177 logger.Println("FATAL " + fmt.Sprint(v...)) 178 os.Exit(1) 179 } 180 181 //-------------------------------------- 182 // CPU profile 183 //-------------------------------------- 184 func runCPUProfile() { 185 186 f, err := os.Create(cpuprofile) 187 if err != nil { 188 fatal(err) 189 } 190 pprof.StartCPUProfile(f) 191 192 c := make(chan os.Signal, 1) 193 signal.Notify(c, os.Interrupt) 194 go func() { 195 for sig := range c { 196 infof("captured %v, stopping profiler and exiting..", sig) 197 pprof.StopCPUProfile() 198 os.Exit(1) 199 } 200 }() 201 } 202 203 //-------------------------------------- 204 // Testing 205 //-------------------------------------- 206 func directSet() { 207 c := make(chan bool, 1000) 208 for i := 0; i < 1000; i++ { 209 go send(c) 210 } 211 212 for i := 0; i < 1000; i++ { 213 <-c 214 } 215 } 216 217 func send(c chan bool) { 218 for i := 0; i < 10; i++ { 219 command := &SetCommand{} 220 command.Key = "foo" 221 command.Value = "bar" 222 command.ExpireTime = time.Unix(0, 0) 223 r.Do(command) 224 } 225 c <- true 226 }