Beispiel #1
0
/* 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()
	}
}