raft.go
func (r *Raft) electSelf() <-chan *voteResult {
	// Create a response channel
	respCh := make(chan *voteResult, len(r.configurations.latest.Servers))

	// Increment the term
	r.setCurrentTerm(r.getCurrentTerm() + 1)

	// Construct the request
	lastIdx, lastTerm := r.getLastEntry()
	req := &RequestVoteRequest{
		RPCHeader:    r.getRPCHeader(),
		Term:         r.getCurrentTerm(),
		Candidate:    r.trans.EncodePeer(r.localID, r.localAddr),
		LastLogIndex: lastIdx,
		LastLogTerm:  lastTerm,
	}

	// Construct a function to ask for a vote
	askPeer := func(peer Server) {
		r.goFunc(func() {
			defer metrics.MeasureSince([]string{"raft", "candidate", "electSelf"}, time.Now())
			resp := &voteResult{voterID: peer.ID}
			err := r.trans.RequestVote(peer.ID, peer.Address, req, &resp.RequestVoteResponse)
			if err != nil {
				r.logger.Error(fmt.Sprintf("Failed to make RequestVote RPC to %v: %v", peer, err))
				resp.Term = req.Term
				resp.Granted = false
			}
			respCh <- resp
		})
	}

	// For each peer, request a vote
	for _, server := range r.configurations.latest.Servers {
		if server.Suffrage == Voter {
			if server.ID == r.localID {
				// Persist a vote for ourselves
				if err := r.persistVote(req.Term, req.Candidate); err != nil {
					r.logger.Error(fmt.Sprintf("Failed to persist vote : %v", err))
					return nil
				}
				// Include our own vote
				respCh <- &voteResult{
					RequestVoteResponse: RequestVoteResponse{
						RPCHeader: r.getRPCHeader(),
						Term:      req.Term,
						Granted:   true,
					},
					voterID: r.localID,
				}
			} else {
				askPeer(server)
			}
		}
	}

	return respCh
}
func (r *Raft) electSelf() <-chan *voteResult {
	// Create a response channel
	respCh := make(chan *voteResult, len(r.configurations.latest.Servers))

	// Increment the term
	r.setCurrentTerm(r.getCurrentTerm() + 1)

	// Construct the request
	lastIdx, lastTerm := r.getLastEntry()
	req := &RequestVoteRequest{
		RPCHeader:    r.getRPCHeader(),
		Term:         r.getCurrentTerm(),
		Candidate:    r.trans.EncodePeer(r.localID, r.localAddr),
		LastLogIndex: lastIdx,
		LastLogTerm:  lastTerm,
	}

	// Construct a function to ask for a vote
	askPeer := func(peer Server) {
		r.goFunc(func() {
			defer metrics.MeasureSince([]string{"raft", "candidate", "electSelf"}, time.Now())
			resp := &voteResult{voterID: peer.ID}
			err := r.trans.RequestVote(peer.ID, peer.Address, req, &resp.RequestVoteResponse)
			if err != nil {
				r.logger.Error(fmt.Sprintf("Failed to make RequestVote RPC to %v: %v", peer, err))
				resp.Term = req.Term
				resp.Granted = false
			}
			respCh <- resp
		})
	}

	// For each peer, request a vote
	for _, server := range r.configurations.latest.Servers {
		if server.Suffrage == Voter {
			if server.ID == r.localID {
				// Persist a vote for ourselves
				if err := r.persistVote(req.Term, req.Candidate); err != nil {
					r.logger.Error(fmt.Sprintf("Failed to persist vote : %v", err))
					return nil
				}
				// Include our own vote
				respCh <- &voteResult{
					RequestVoteResponse: RequestVoteResponse{
						RPCHeader: r.getRPCHeader(),
						Term:      req.Term,
						Granted:   true,
					},
					voterID: r.localID,
				}
			} else {
				askPeer(server)
			}
		}
	}

	return respCh
}
func ( r * Raft ) electSelf ( ) <- chan * voteResult { // Create a response channel respCh := make ( chan * voteResult , len ( r . configurations . latest . Servers ) ) // Increment the term r . setCurrentTerm ( r . getCurrentTerm ( ) + 1 ) // Construct the request lastIdx , lastTerm := r . getLastEntry ( ) req := & RequestVoteRequest { RPCHeader : r . getRPCHeader ( ) , Term : r . getCurrentTerm ( ) , Candidate : r . trans . EncodePeer ( r . localID , r . localAddr ) , LastLogIndex : lastIdx , LastLogTerm : lastTerm , } // Construct a function to ask for a vote askPeer := func ( peer Server ) { r . goFunc ( func ( ) { defer metrics . MeasureSince ( [ ] string { " " , " " , " " } , time . Now ( ) ) resp := & voteResult { voterID : peer . ID } err := r . trans . RequestVote ( peer . ID , peer . Address , req , & resp . RequestVoteResponse ) if err != nil { r . logger . Error ( fmt . Sprintf ( " " , peer , err ) ) resp . Term = req . Term resp . Granted = false } respCh <- resp } ) } // For each peer, request a vote for _ , server := range r . configurations . latest . Servers { if server . Suffrage == Voter { if server . ID == r . localID { // Persist a vote for ourselves if err := r . persistVote ( req . Term , req . Candidate ) ; err != nil { r . logger . Error ( fmt . Sprintf ( " " , err ) ) return nil } // Include our own vote respCh <- & voteResult { RequestVoteResponse : RequestVoteResponse { RPCHeader : r . getRPCHeader ( ) , Term : req . Term , Granted : true , } , voterID : r . localID , } } else { askPeer ( server ) } } } return respCh }
// electSelf is used to send a RequestVote RPC to all peers, and vote for
// ourself. This has the side affecting of incrementing the current term. The
// response channel returned is used to wait for all the responses (including a
// vote for ourself). This must only be called from the main thread.
electSelf is used to send a RequestVote RPC to all peers and vote for ourself . This has the side affecting of incrementing the current term . The response channel returned is used to wait for all the responses ( including a vote for ourself ) . This must only be called from the main thread .