@Test public void requestVote() throws Exception { }
public int requestVote(int term, UUID candidate, int lastLogIndex, int lastLogTerm) throws InvalidTermException, AlreadyVotedException, CandidateBehindException { logger.fine( String.format( "%s received vote request from %s (term=%d, lastLogIndex=%d, lastLogTerm=%d)", pState.myServerID, candidate, term, lastLogIndex, lastLogTerm)); if (!candidate.equals( pState.myServerID)) { this.respondToRemoteTerm(term); } int localLogSize, currentTerm, myLastLogTerm = -1, myLastLogIndex; UUID votedFor; synchronized (pState) { currentTerm = pState.getCurrentTerm(); votedFor = pState.getVotedFor(); localLogSize = pState.log().size(); myLastLogIndex = this.lastLogIndex(); if (myLastLogIndex != -1) { myLastLogTerm = pState.log().get(myLastLogIndex).term; } } if (term < currentTerm) { throw new InvalidTermException( "Server: Received voting request for old leader term " + term + ", current term " + currentTerm + ". No vote granted.", currentTerm); } if (votedFor.equals(NO_LEADER) || votedFor.equals(candidate)) { logger.fine( String.format( "%s deciding whether to vote for %s: local log size = %d", pState.myServerID, candidate, localLogSize)); if (lastLogIndex >= myLastLogIndex && (localLogSize == 0 || lastLogTerm >= myLastLogTerm)) { logger.fine( String.format("%s decided to vote for %s", pState.myServerID, candidate)); pState.setVotedFor(candidate, votedFor); return currentTerm; } else { throw new CandidateBehindException( String.format( "Candidate is behind. Candidate last log index, term = (%d, %d), current last log index, term = (%d, %d)", lastLogIndex, lastLogTerm, myLastLogIndex, myLastLogTerm), currentTerm); } } else { throw new AlreadyVotedException( String.format( "Request to vote for %s but already voted for %s (current term = %d)", candidate, votedFor, currentTerm), currentTerm); } }
Server implements RemoteRaftServer { public int requestVote(int term, UUID candidate, int lastLogIndex, int lastLogTerm) throws InvalidTermException, AlreadyVotedException, CandidateBehindException { logger.fine( String.format( "%s received vote request from %s (term=%d, lastLogIndex=%d, lastLogTerm=%d)", pState.myServerID, candidate, term, lastLogIndex, lastLogTerm)); if (!candidate.equals( pState.myServerID)) { this.respondToRemoteTerm(term); } int localLogSize, currentTerm, myLastLogTerm = -1, myLastLogIndex; UUID votedFor; synchronized (pState) { currentTerm = pState.getCurrentTerm(); votedFor = pState.getVotedFor(); localLogSize = pState.log().size(); myLastLogIndex = this.lastLogIndex(); if (myLastLogIndex != -1) { myLastLogTerm = pState.log().get(myLastLogIndex).term; } } if (term < currentTerm) { throw new InvalidTermException( "Server: Received voting request for old leader term " + term + ", current term " + currentTerm + ". No vote granted.", currentTerm); } if (votedFor.equals(NO_LEADER) || votedFor.equals(candidate)) { logger.fine( String.format( "%s deciding whether to vote for %s: local log size = %d", pState.myServerID, candidate, localLogSize)); if (lastLogIndex >= myLastLogIndex && (localLogSize == 0 || lastLogTerm >= myLastLogTerm)) { logger.fine( String.format("%s decided to vote for %s", pState.myServerID, candidate)); pState.setVotedFor(candidate, votedFor); return currentTerm; } else { throw new CandidateBehindException( String.format( "Candidate is behind. Candidate last log index, term = (%d, %d), current last log index, term = (%d, %d)", lastLogIndex, lastLogTerm, myLastLogIndex, myLastLogTerm), currentTerm); } } else { throw new AlreadyVotedException( String.format( "Request to vote for %s but already voted for %s (current term = %d)", candidate, votedFor, currentTerm), currentTerm); } } }
Server implements RemoteRaftServer { public int requestVote(int term, UUID candidate, int lastLogIndex, int lastLogTerm) throws InvalidTermException, AlreadyVotedException, CandidateBehindException { logger.fine( String.format( "%s received vote request from %s (term=%d, lastLogIndex=%d, lastLogTerm=%d)", pState.myServerID, candidate, term, lastLogIndex, lastLogTerm)); if (!candidate.equals( pState.myServerID)) { this.respondToRemoteTerm(term); } int localLogSize, currentTerm, myLastLogTerm = -1, myLastLogIndex; UUID votedFor; synchronized (pState) { currentTerm = pState.getCurrentTerm(); votedFor = pState.getVotedFor(); localLogSize = pState.log().size(); myLastLogIndex = this.lastLogIndex(); if (myLastLogIndex != -1) { myLastLogTerm = pState.log().get(myLastLogIndex).term; } } if (term < currentTerm) { throw new InvalidTermException( "Server: Received voting request for old leader term " + term + ", current term " + currentTerm + ". No vote granted.", currentTerm); } if (votedFor.equals(NO_LEADER) || votedFor.equals(candidate)) { logger.fine( String.format( "%s deciding whether to vote for %s: local log size = %d", pState.myServerID, candidate, localLogSize)); if (lastLogIndex >= myLastLogIndex && (localLogSize == 0 || lastLogTerm >= myLastLogTerm)) { logger.fine( String.format("%s decided to vote for %s", pState.myServerID, candidate)); pState.setVotedFor(candidate, votedFor); return currentTerm; } else { throw new CandidateBehindException( String.format( "Candidate is behind. Candidate last log index, term = (%d, %d), current last log index, term = (%d, %d)", lastLogIndex, lastLogTerm, myLastLogIndex, myLastLogTerm), currentTerm); } } else { throw new AlreadyVotedException( String.format( "Request to vote for %s but already voted for %s (current term = %d)", candidate, votedFor, currentTerm), currentTerm); } } Server(StateMachineApplier applier); }
Server implements RemoteRaftServer { public int requestVote(int term, UUID candidate, int lastLogIndex, int lastLogTerm) throws InvalidTermException, AlreadyVotedException, CandidateBehindException { logger.fine( String.format( "%s received vote request from %s (term=%d, lastLogIndex=%d, lastLogTerm=%d)", pState.myServerID, candidate, term, lastLogIndex, lastLogTerm)); if (!candidate.equals( pState.myServerID)) { this.respondToRemoteTerm(term); } int localLogSize, currentTerm, myLastLogTerm = -1, myLastLogIndex; UUID votedFor; synchronized (pState) { currentTerm = pState.getCurrentTerm(); votedFor = pState.getVotedFor(); localLogSize = pState.log().size(); myLastLogIndex = this.lastLogIndex(); if (myLastLogIndex != -1) { myLastLogTerm = pState.log().get(myLastLogIndex).term; } } if (term < currentTerm) { throw new InvalidTermException( "Server: Received voting request for old leader term " + term + ", current term " + currentTerm + ". No vote granted.", currentTerm); } if (votedFor.equals(NO_LEADER) || votedFor.equals(candidate)) { logger.fine( String.format( "%s deciding whether to vote for %s: local log size = %d", pState.myServerID, candidate, localLogSize)); if (lastLogIndex >= myLastLogIndex && (localLogSize == 0 || lastLogTerm >= myLastLogTerm)) { logger.fine( String.format("%s decided to vote for %s", pState.myServerID, candidate)); pState.setVotedFor(candidate, votedFor); return currentTerm; } else { throw new CandidateBehindException( String.format( "Candidate is behind. Candidate last log index, term = (%d, %d), current last log index, term = (%d, %d)", lastLogIndex, lastLogTerm, myLastLogIndex, myLastLogTerm), currentTerm); } } else { throw new AlreadyVotedException( String.format( "Request to vote for %s but already voted for %s (current term = %d)", candidate, votedFor, currentTerm), currentTerm); } } Server(StateMachineApplier applier); UUID getMyServerID(); void start(); void stop(); int appendEntries(
            int term,
            UUID leader,
            int prevLogIndex,
            int prevLogTerm,
            List<LogEntry> entries,
            int leaderCommit); int requestVote(int term, UUID candidate, int lastLogIndex, int lastLogTerm); Object applyToStateMachine(Object operation); void addServer(UUID id, RemoteRaftServer server); }
Server implements RemoteRaftServer { public int requestVote(int term, UUID candidate, int lastLogIndex, int lastLogTerm) throws InvalidTermException, AlreadyVotedException, CandidateBehindException { logger.fine( String.format( "%s received vote request from %s (term=%d, lastLogIndex=%d, lastLogTerm=%d)", pState.myServerID, candidate, term, lastLogIndex, lastLogTerm)); if (!candidate.equals( pState.myServerID)) { this.respondToRemoteTerm(term); } int localLogSize, currentTerm, myLastLogTerm = -1, myLastLogIndex; UUID votedFor; synchronized (pState) { currentTerm = pState.getCurrentTerm(); votedFor = pState.getVotedFor(); localLogSize = pState.log().size(); myLastLogIndex = this.lastLogIndex(); if (myLastLogIndex != -1) { myLastLogTerm = pState.log().get(myLastLogIndex).term; } } if (term < currentTerm) { throw new InvalidTermException( "Server: Received voting request for old leader term " + term + ", current term " + currentTerm + ". No vote granted.", currentTerm); } if (votedFor.equals(NO_LEADER) || votedFor.equals(candidate)) { logger.fine( String.format( "%s deciding whether to vote for %s: local log size = %d", pState.myServerID, candidate, localLogSize)); if (lastLogIndex >= myLastLogIndex && (localLogSize == 0 || lastLogTerm >= myLastLogTerm)) { logger.fine( String.format("%s decided to vote for %s", pState.myServerID, candidate)); pState.setVotedFor(candidate, votedFor); return currentTerm; } else { throw new CandidateBehindException( String.format( "Candidate is behind. Candidate last log index, term = (%d, %d), current last log index, term = (%d, %d)", lastLogIndex, lastLogTerm, myLastLogIndex, myLastLogTerm), currentTerm); } } else { throw new AlreadyVotedException( String.format( "Request to vote for %s but already voted for %s (current term = %d)", candidate, votedFor, currentTerm), currentTerm); } } Server(StateMachineApplier applier); UUID getMyServerID(); void start(); void stop(); int appendEntries(
            int term,
            UUID leader,
            int prevLogIndex,
            int prevLogTerm,
            List<LogEntry> entries,
            int leaderCommit); int requestVote(int term, UUID candidate, int lastLogIndex, int lastLogTerm); Object applyToStateMachine(Object operation); void addServer(UUID id, RemoteRaftServer server); static final int LEADER_HEARTBEAT_TIMEOUT; }