Beispiel #1
0
func (c *Client) lookup() error {
	for {
		addr := c.addrs[rand.Intn(len(c.addrs))]
		cli, err := proto.DialMsgpack(addr, time.Second)
		if err == nil {
			c.cli = cli
			return nil
		}
		c.log.Error("connect", "error", err)
		time.Sleep(time.Second)
	}
	return nil
}
Beispiel #2
0
func (s *Server) forward(method string, req, rep interface{}) (done bool, err error) {
	if s.raft.State() == raft.Leader {
		return false, nil
	}

	done = true

	leader := s.raft.Leader()
	if leader == "" {
		err = proto.ErrNoLeader
		return
	}

	s.mutex.Lock()
	cli, ok := s.conns[leader]
	s.mutex.Unlock()
	if !ok {
		// FIXME connection timeout hard code
		cli, err = proto.DialMsgpack(leader, time.Second*3)
		if err != nil {
			return
		}
		// cache connection
		s.mutex.Lock()
		s.conns[leader] = cli
		s.mutex.Unlock()
	}

	err = cli.Call(method, req, rep)
	if err != nil {
		// if is ServerError, do not close, otherwise close connection
		if _, ok := err.(rpc.ServerError); ok {
			return
		}
		cli.Close()
		s.mutex.Lock()
		delete(s.conns, leader)
		s.mutex.Unlock()
		return
	}

	return
}