Esempio n. 1
0
func (z *ZkConn) ManageTree(node string, callbacks ...EventCallbacks) {
	if len(callbacks) == 0 {
		return
	}

	children, _, eventCh, err := z.Conn.ChildrenW(node)
	if err != nil {
		logger.Errorf("[zkconn %d] ChildrenW(%s): %s", z, node, err)
		return
	}

	for _, child := range children {
		childNode := path.Join(node, child)
		z.ManageNode(childNode, callbacks[0])
		if len(callbacks) > 1 {
			go z.ManageTree(childNode, callbacks[1:]...)
		}
	}

	for {
		ev := <-eventCh

		if ev.State == zookeeper.STATE_CLOSED {
			// shutdown was called on ZkConn?
			return
		}

		if ev.State == zookeeper.STATE_EXPIRED_SESSION ||
			ev.State == zookeeper.STATE_CONNECTING {
			logger.Printf("[zkconn %d] connection lost, stop watching %s", z, node)
			return
		}

		switch ev.Type {
		case zookeeper.EVENT_DELETED:
			logger.Printf("[zkconn %d] node deleted, stop watching %s", z, node)
			return
		case zookeeper.EVENT_CHILD:
			prev := children
			children, _, eventCh, err = z.Conn.ChildrenW(node)
			if err != nil {
				logger.Errorf("[zkconn %d] ChildrenW(%s): %s", z, node, err)
				return
			}
			for _, child := range ArrayDiff(children, prev) {
				childNode := path.Join(node, child)
				z.ManageNode(childNode, callbacks[0])
				if len(callbacks) > 1 {
					go z.ManageTree(childNode, callbacks[1:]...)
				}
			}
		}
	}
}
Esempio n. 2
0
func (s *Server) CheckStatus(tout time.Duration) {
	r, _ := http.NewRequest("GET", "http://"+s.Address+"/healthz", nil)

	resErrCh := make(chan ResponseError)
	go s.RoundTrip(r, resErrCh)

	select {
	case resErr := <-resErrCh:
		if resErr.Error == nil {
			defer resErr.Response.Body.Close()

			//if status has changed then log
			if s.Status.ParseAndSet(resErr.Response) {
				logger.Printf("[server %s] status code changed to %d\n", s.Address, resErr.Response.StatusCode)
			}
		} else {
			//if status has changed then log
			if s.Status.Set(StatusCritical) {
				logger.Errorf("[server %s] status set to critical! : %s\n", s.Address, resErr.Error)
			}
		}
	case <-time.After(tout):
		s.Transport.CancelRequest(r)
		if s.Status.Set(StatusCritical) {
			logger.Errorf("[server %s] status set to critical due to timeout!\n", s.Address)
		}
	}
}
Esempio n. 3
0
func (z *ZkConn) dialExclusive() {
	z.Lock()

	for err := z.dial(); err != nil; {
		logger.Printf("[zkconn %p] z.dial(): %s", z, err)
	}

	z.Unlock()

	z.ResetCh <- true
}
Esempio n. 4
0
func (p *Pool) Handle(logRecord *logger.HAProxyLogRecord) {
	pTime := time.Now()
	if p.Dummy {
		logger.Printf("[pool %s] Dummy", p.Name)
		logRecord.Error(logger.BadGatewayMsg, http.StatusBadGateway)
		logRecord.Terminate("Pool: " + logger.BadGatewayMsg)
		return
	}
	p.Metrics.ConnectionStart()
	defer p.Metrics.ConnectionDone()

	server := p.Next()
	if server == nil {
		// reachable when all servers in pool report StatusMaintenance
		logger.Printf("[pool %s] no server", p.Name)
		logRecord.Error(logger.ServiceUnavailableMsg, http.StatusServiceUnavailable)
		logRecord.Terminate("Pool: " + logger.ServiceUnavailableMsg)
		return
	}
	logRecord.PoolUpdateRecord(p.Name, p.Metrics.GetActiveConnections(), p.Metrics.GetTotalConnections(), pTime)
	server.Handle(logRecord, p.Config.RequestTimeout)
}
Esempio n. 5
0
func (z *ZkConn) waitOnConnect() error {
	for {
		ev := <-z.eventCh
		logger.Printf("[zkconn %p] eventCh-> %d %s in waitOnConnect", z, ev.State, ev)

		switch ev.State {
		case zookeeper.STATE_CONNECTED:
			return nil
		case zookeeper.STATE_CONNECTING:
			continue
		default:
			return errors.New(ev.String())
		}
	}
}
Esempio n. 6
0
func (z *ZkConn) monitorEventCh() {
	for {
		select {
		case ev := <-z.eventCh:
			logger.Printf("[zkconn %p] eventCh -> %d %s in monitorEventCh", z, ev.State, ev)
			lastEvent = ev
			if ev.State == zookeeper.STATE_EXPIRED_SESSION ||
				ev.State == zookeeper.STATE_CONNECTING {
				z.dialExclusive()
				return
			}

		case <-z.killCh:
			return
		}
	}
}
Esempio n. 7
0
func (z *ZkConn) ManageNode(node string, callbacks EventCallbacks) error {
	content, _, eventCh, err := z.Conn.GetW(node)
	if err != nil {
		logger.Errorf("[zkconn %d] GetW(%s): %s", z, node, err)
		return err
	}

	callbacks.Created(node, content)

	go func() {
		for {
			ev := <-eventCh

			if ev.State == zookeeper.STATE_CLOSED {
				// shutdown was called on ZkConn?
				return
			}

			if ev.State == zookeeper.STATE_EXPIRED_SESSION ||
				ev.State == zookeeper.STATE_CONNECTING {
				logger.Printf("[zkconn %d] connection lost, stop watching %s", z, node)
				return
			}

			switch ev.Type {
			case zookeeper.EVENT_DELETED:
				callbacks.Deleted(node)
				return
			case zookeeper.EVENT_CHANGED:
				content, _, eventCh, err = z.Conn.GetW(node)
				if err != nil {
					logger.Errorf("[zkconn %d] GetW(%s): %s", z, node, err)
					return
				}
				callbacks.Changed(node, content)
			}
		}
	}()

	return nil
}
Esempio n. 8
0
func (s *Server) Handle(logRecord *logger.HAProxyLogRecord, tout time.Duration) {
	sTime := time.Now()
	s.Metrics.RequestStart()
	defer s.Metrics.RequestDone()

	// X-Forwarded-For; we are a proxy.
	ip := strings.Split(logRecord.Request.RemoteAddr, ":")[0]
	logRecord.Request.Header.Add("X-Forwarded-For", ip)
	logRecord.ServerUpdateRecord(s.Address, s.Metrics.RequestsServiced, s.Metrics.Cost(), sTime)
	resErrCh := make(chan ResponseError)
	tstart := time.Now()
	go s.RoundTrip(logRecord.Request, resErrCh)
	tend := time.Now()
	logRecord.UpdateTr(tstart, tend)
	select {
	case resErr := <-resErrCh:
		if resErr.Error == nil {
			defer resErr.Response.Body.Close()

			logRecord.CopyHeaders(resErr.Response.Header)
			logRecord.WriteHeader(resErr.Response.StatusCode)

			err := logRecord.Copy(resErr.Response.Body)
			if err != nil {
				logger.Errorf("[server %s] failed attempting to copy response body: %s\n", s.Address, err)
			} else {
				logRecord.Log()
			}
		} else {
			logger.Errorf("[server %s] failed attempting the roundtrip: %s\n", s.Address, resErr.Error)
			logRecord.Error(logger.BadGatewayMsg, http.StatusBadGateway)
			logRecord.Terminate("Server: " + logger.BadGatewayMsg)
		}
	case <-time.After(tout):
		s.Transport.CancelRequest(logRecord.Request)
		logger.Printf("[server %s] round trip timed out!", s.Address)
		logRecord.Error(logger.GatewayTimeoutMsg, http.StatusGatewayTimeout)
		logRecord.Terminate("Server: " + logger.GatewayTimeoutMsg)
	}
}