RaftAlgorithm implements RPCReceiver, Raft { synchronized void becomeFollower(long newCurrentTerm, @Nullable String newLeader) throws StorageException { long currentTerm = store.getCurrentTerm(); checkArgument(currentTerm < newCurrentTerm, "currentTerm:%s newCurrentTerm:%s", currentTerm, newCurrentTerm); logRoleChange(newCurrentTerm, role, Role.FOLLOWER); stopHeartbeatTimeout(); store.setCurrentTerm(newCurrentTerm); setFollowerState(newLeader); } RaftAlgorithm(
            Random random,
            Timer timer,
            RPCSender sender,
            Store store,
            Log log,
            SnapshotsStore snapshotsStore,
            RaftListener listener,
            String self,
            Set<String> cluster);  RaftAlgorithm(
            Random random,
            Timer timer,
            RPCSender sender,
            Store store,
            Log log,
            SnapshotsStore snapshotsStore,
            RaftListener listener,
            String self,
            Set<String> cluster,
            int minEntriesToSnapshot,
            long snapshotCheckInterval,
            long rpcTimeout,
            long minElectionTimeout,
            long additionalElectionTimeoutRange,
            long heartbeatInterval,
            TimeUnit timeoutTimeUnit); synchronized void initialize(); synchronized void start(); synchronized void stop(); @Override synchronized void onRequestVote(String server, long term, long lastLogIndex, long lastLogTerm); @Override synchronized void onRequestVoteReply(String server, long term, boolean voteGranted); @Override synchronized void onAppendEntries(String server, long term, long commitIndex, long prevLogIndex, long prevLogTerm, @Nullable Collection<LogEntry> entries); @Override synchronized void onAppendEntriesReply(String server, long term, long prevLogIndex, long entryCount, boolean applied); @Override synchronized void snapshotWritten(SnapshotWriter snapshotWriter); @Override synchronized @Nullable Committed getNextCommitted(long indexToSearchFrom); @Override synchronized ListenableFuture<Void> submitCommand(Command command);  }
@Test public void shouldNotCrashIfLeadershipNotificationListenerThrowsAnException() throws StorageException { doThrow(IllegalStateException.class).when(listener).onLeadershipChange(anyString()); algorithm.becomeFollower(3, S_02); assertThatSelfTransitionedToFollower(3, 0, S_02, true); algorithm.becomeFollower(4, S_02); assertThatSelfTransitionedToFollower(4, 0, S_02, true); assertThatLogContains( SENTINEL() ); assertThatTermAndCommitIndexHaveValues(4, 0); }
@Test public void shouldIssueRequestVoteWithCorrectLogPrefix() throws StorageException { insertIntoLog( SENTINEL(), NOOP(1, 1), NOOP(2, 1), NOOP(3, 2) ); algorithm.becomeFollower(2, null); assertThatSelfTransitionedToFollower(2, 0, null, false); triggerElection(3); Collection<RequestVote> requestVotes = getRPCs(4, RequestVote.class); assertThatRPCsSentTo(requestVotes, S_01, S_02, S_03, S_04); assertThatRequestVotesHaveValues(requestVotes, 3, 3, 2); assertThatNoMoreRPCsWereSent(); assertThatLogContains( SENTINEL(), NOOP(1, 1), NOOP(2, 1), NOOP(3, 2) ); assertThatTermAndCommitIndexHaveValues(3, 0); }