func (c *Cluster) Vote(vreq *ClusterVoteRequest, response *ClusterVoteResponse) error {
	respChan := make(chan ClusterVoteResponse, 1)
	c.fo.electionVote <- &ClusterVote{
		req:  vreq,
		resp: respChan}
	*response = <-respChan
	return nil
}
Vote processes request for a vote from a candidate.
package broker
import (
	"log"
	"math/rand"
	"net/rpc"
	"time"
)
type clusterFailover struct {
	leader string
	term int
	heartBeat time.Duration
	voteTimeout int
	activeNodes []string
	nodeFailCountLimit int
	leaderPing chan *ClusterPing
	electionVote chan *ClusterVote
	done chan bool
}
type clusterFailoverConfig struct {
	Enabled bool `json:"enabled"`
	Heartbeat int `json:"heartbeat"`
	VoteAfter int `json:"vote_after"`
	NodeFailAfter int `json:"node_fail_after"`
}
type ClusterPing struct {
	Leader string
	Term int
	Signature string
	Nodes []string
}
type ClusterVoteRequest struct {
	Node string
	Term int
}
type ClusterVoteResponse struct {
	Result bool
	Term int
}
type ClusterVote struct {
	req  *ClusterVoteRequest
	resp chan ClusterVoteResponse
}
func (c *Cluster) failoverInit(config *clusterFailoverConfig) bool {
	if config == nil || !config.Enabled {
		return false
	}
	if len(c.nodes) < 2 {
		log.Printf("cluster: failover disabled; need at least 3 nodes, got %d", len(c.nodes)+1)
		return false
	}
	var activeNodes []string
	for _, node := range c.nodes {
		activeNodes = append(activeNodes, node.name)
	}
	activeNodes = append(activeNodes, c.thisNodeName)
	c.rehash(activeNodes)
	rand.Seed(time.Now().UnixNano())
	hb := time.Duration(config.Heartbeat) * time.Millisecond
	hb = (hb >> 1) + (hb >> 2) + time.Duration(rand.Intn(int(hb>>1)))
	c.fo = &clusterFailover{
		activeNodes:        activeNodes,
		heartBeat:          hb,
		voteTimeout:        config.VoteAfter,
		nodeFailCountLimit: config.NodeFailAfter,
		leaderPing:         make(chan *ClusterPing, config.VoteAfter),
		electionVote:       make(chan *ClusterVote, len(c.nodes)),
		done:               make(chan bool, 1)}
	log.Println("cluster: failover mode enabled")
	return true
}
func (c *Cluster) Ping(ping *ClusterPing, unused *bool) error {
	select {
	case c.fo.leaderPing <- ping:
	default:
	}
	return nil
}