/* TODO: Implement more probes */ func (s *Server) probe_backends(probe time.Duration) { transport := http.Transport{Dial: dialTimeout} client := &http.Client{ Transport: &transport, } for { time.Sleep(probe) for vhost, backends := range s.proxy { fmt.Println(backends) err := s.populate_proxies(vhost) if err != nil { utils.Log(fmt.Sprintf("Cleaned entries from vhost: %s", vhost)) continue } is_dead := make(map[string]bool) removed := 0 for backend := range backends { backend = backend - removed utils.Log(fmt.Sprintf( "vhost: %s backends: %s", vhost, s.proxy[vhost][backend].Backend)) if is_dead[s.proxy[vhost][backend].Backend] == true { utils.Log(fmt.Sprintf("Removing dead backend: %s", s.proxy[vhost][backend].Backend)) s.mu.Lock() s.proxy[vhost] = s.proxy[vhost][:backend+copy(s.proxy[vhost][backend:], s.proxy[vhost][backend+1:])] s.vcount[vhost][s.proxy[vhost][backend].Backend]-- s.mu.Unlock() removed++ continue } _, err := client.Get(s.proxy[vhost][backend].Backend) if err != nil { utils.Log(fmt.Sprintf("Removing dead backend: %s with error %s", s.proxy[vhost][backend].Backend, err)) is_dead[s.proxy[vhost][backend].Backend] = true s.mu.Lock() s.proxy[vhost] = s.proxy[vhost][:backend+copy(s.proxy[vhost][backend:], s.proxy[vhost][backend+1:])] s.vcount[vhost][s.proxy[vhost][backend].Backend]-- s.mu.Unlock() removed++ } else { utils.Log(fmt.Sprintf("Alive: %s", s.proxy[vhost][backend].Backend)) } } } transport.CloseIdleConnections() } }
// Goroutine to run a robot func robot() { var payload interface{} transport := new(http.Transport) transport.DisableKeepAlives = true client := &http.Client{Transport: transport} id := uuid.New() // login resp, err := client.PostForm(msgurl, url.Values{"command": {"login"}, "id": {id}}) if err != nil { log.Printf("http login error: %v", err) return } body, err := ioutil.ReadAll(resp.Body) resp.Body.Close() if err != nil { log.Printf("http login error: %v", err) return } // extract payload err = json.Unmarshal(body, &payload) if err != nil { log.Printf("json unmarshal error: %v", err) log.Printf("json data: %s", string(body)) return } outerObj := payload.(map[string]interface{}) respType := outerObj["type"].(string) // check for login errors if respType == "status" { status := outerObj["status"].(string) if status == "error" { message := outerObj["message"].(string) log.Printf("chat server login error: %s", message) return } } // get additional user data //publicId := outerObj["publicid"].(string) //userName := outerObj["username"].(string) // run the poller go robotPoller(id) msgCount := 0 // main loop for { // send chat resp, err = client.PostForm(msgurl, url.Values{ "command": {"broadcast"}, "id": {id}, "message": {fmt.Sprintf("message %d", msgCount)}, }) msgCount++ if err != nil { log.Printf("http broadcast error: %v", err) return } body, err = ioutil.ReadAll(resp.Body) resp.Body.Close() // check for broadcast errors if respType == "status" { status := outerObj["status"].(string) if status == "error" { message := outerObj["message"].(string) log.Printf("chat server broadcast error: %s", message) return } } // sleep a bit duration := rand.Int31n(int32(maxDelay-minDelay)) + int32(minDelay) time.Sleep(time.Duration(duration) * time.Millisecond) transport.CloseIdleConnections() } }
// Goroutine to run a long poll thread for a robot func robotPoller(id string) { var payload interface{} transport := new(http.Transport) transport.DisableKeepAlives = true client := &http.Client{Transport: transport} for { // send in a poll request and wait for response resp, err := client.PostForm(pollurl, url.Values{"id": {id}}) if err != nil { log.Printf("poller post error: %v", err) return } //log.Printf("************** %v %v", resp, err) body, err := ioutil.ReadAll(resp.Body) resp.Body.Close() if err != nil { log.Printf("http poll request error: %v", err) return } // extract payload err = json.Unmarshal(body, &payload) if err != nil { log.Printf("json poll unmarshal error: %v", err) log.Printf("json poll data: %s", string(body)) return } outerObj := payload.([]interface{}) for _, v := range outerObj { message := v.(map[string]interface{}) respType := message["type"].(string) // check for login errors if respType == "status" { status := message["status"].(string) if status == "error" { message := message["message"].(string) log.Printf("chat server pollrequest error: %s", message) return } } // parse message switch respType { case "message": //log.Printf("%s: message: %s: %s", id, message["username"].(string), message["message"].(string)) case "newuser": //log.Printf("%s: new user: %s", id, message["username"].(string)) default: log.Printf("%s: unknown type: %s", id, respType) } } transport.CloseIdleConnections() } }