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