@Test public void testRequestVoteWithOlderTerm() throws Exception { Candidate candidate = new Candidate(mockRaftLog, scheduler, 150, mockRaftClient); candidate.init(mockRaftStateContext); Replica mockCandidate = config.getReplica("other"); RequestVote request = RequestVote.newBuilder() .setCandidateId(mockCandidate.toString()) .setLastLogIndex(1L) .setLastLogTerm(1L) .setTerm(1L) .build(); candidate.requestVote(mockRaftStateContext, request); verify(mockRaftLog).currentTerm(3L); verify(mockRaftLog, times(1)).currentTerm(anyLong()); verify(mockRaftLog).votedFor(java.util.Optional.of(self)); verify(mockRaftLog, never()).votedFor(java.util.Optional.of(mockCandidate)); verify(mockRaftLog, times(1)).votedFor(any(Optional.class)); verify(mockRaftLog, never()).commitIndex(anyLong()); verify(mockRaftStateContext).setState(any(Candidate.class), eq(Raft.StateType.LEADER)); verifyZeroInteractions(mockRaftClient); }
@Override public void init(@Nonnull final RaftStateContext ctx) { final RaftLog log = getLog(); log.currentTerm(log.currentTerm() + 1); log.votedFor(Optional.of(log.self())); LOGGER.debug("Election starting for term {}", log.currentTerm()); List<CompletableFuture<RequestVoteResponse>> responses = log.members().stream().map(member -> sendVoteRequest(ctx, member) ).collect(toList()); responses.add(SUCCESS_VOTE); electionResult = majorityResponse(responses, voteGranted()); long timeout = electionTimeout + (RAND.nextLong() % electionTimeout); electionTimer = DeadlineTimer.start(scheduler, () -> { LOGGER.debug("Election timeout"); ctx.setState(Candidate.this, CANDIDATE); }, timeout); electionResult.thenAccept(elected -> { checkNotNull(elected); if (elected) { ctx.setState(Candidate.this, LEADER); } }).exceptionally(t -> { if (!electionResult.isCancelled()) { LOGGER.debug("Election failed with exception:", t); } return null; }); }
Candidate extends BaseState { @Override public void init(@Nonnull final RaftStateContext ctx) { final RaftLog log = getLog(); log.currentTerm(log.currentTerm() + 1); log.votedFor(Optional.of(log.self())); LOGGER.debug("Election starting for term {}", log.currentTerm()); List<CompletableFuture<RequestVoteResponse>> responses = log.members().stream().map(member -> sendVoteRequest(ctx, member) ).collect(toList()); responses.add(SUCCESS_VOTE); electionResult = majorityResponse(responses, voteGranted()); long timeout = electionTimeout + (RAND.nextLong() % electionTimeout); electionTimer = DeadlineTimer.start(scheduler, () -> { LOGGER.debug("Election timeout"); ctx.setState(Candidate.this, CANDIDATE); }, timeout); electionResult.thenAccept(elected -> { checkNotNull(elected); if (elected) { ctx.setState(Candidate.this, LEADER); } }).exceptionally(t -> { if (!electionResult.isCancelled()) { LOGGER.debug("Election failed with exception:", t); } return null; }); } }
Candidate extends BaseState { @Override public void init(@Nonnull final RaftStateContext ctx) { final RaftLog log = getLog(); log.currentTerm(log.currentTerm() + 1); log.votedFor(Optional.of(log.self())); LOGGER.debug("Election starting for term {}", log.currentTerm()); List<CompletableFuture<RequestVoteResponse>> responses = log.members().stream().map(member -> sendVoteRequest(ctx, member) ).collect(toList()); responses.add(SUCCESS_VOTE); electionResult = majorityResponse(responses, voteGranted()); long timeout = electionTimeout + (RAND.nextLong() % electionTimeout); electionTimer = DeadlineTimer.start(scheduler, () -> { LOGGER.debug("Election timeout"); ctx.setState(Candidate.this, CANDIDATE); }, timeout); electionResult.thenAccept(elected -> { checkNotNull(elected); if (elected) { ctx.setState(Candidate.this, LEADER); } }).exceptionally(t -> { if (!electionResult.isCancelled()) { LOGGER.debug("Election failed with exception:", t); } return null; }); } @Inject  Candidate(RaftLog log, @RaftExecutor Fiber scheduler,
            @ElectionTimeout long electionTimeout, Client client); }
Candidate extends BaseState { @Override public void init(@Nonnull final RaftStateContext ctx) { final RaftLog log = getLog(); log.currentTerm(log.currentTerm() + 1); log.votedFor(Optional.of(log.self())); LOGGER.debug("Election starting for term {}", log.currentTerm()); List<CompletableFuture<RequestVoteResponse>> responses = log.members().stream().map(member -> sendVoteRequest(ctx, member) ).collect(toList()); responses.add(SUCCESS_VOTE); electionResult = majorityResponse(responses, voteGranted()); long timeout = electionTimeout + (RAND.nextLong() % electionTimeout); electionTimer = DeadlineTimer.start(scheduler, () -> { LOGGER.debug("Election timeout"); ctx.setState(Candidate.this, CANDIDATE); }, timeout); electionResult.thenAccept(elected -> { checkNotNull(elected); if (elected) { ctx.setState(Candidate.this, LEADER); } }).exceptionally(t -> { if (!electionResult.isCancelled()) { LOGGER.debug("Election failed with exception:", t); } return null; }); } @Inject  Candidate(RaftLog log, @RaftExecutor Fiber scheduler,
            @ElectionTimeout long electionTimeout, Client client); @Override void init(@Nonnull final RaftStateContext ctx); @Override void destroy(RaftStateContext ctx); }
Candidate extends BaseState { @Override public void init(@Nonnull final RaftStateContext ctx) { final RaftLog log = getLog(); log.currentTerm(log.currentTerm() + 1); log.votedFor(Optional.of(log.self())); LOGGER.debug("Election starting for term {}", log.currentTerm()); List<CompletableFuture<RequestVoteResponse>> responses = log.members().stream().map(member -> sendVoteRequest(ctx, member) ).collect(toList()); responses.add(SUCCESS_VOTE); electionResult = majorityResponse(responses, voteGranted()); long timeout = electionTimeout + (RAND.nextLong() % electionTimeout); electionTimer = DeadlineTimer.start(scheduler, () -> { LOGGER.debug("Election timeout"); ctx.setState(Candidate.this, CANDIDATE); }, timeout); electionResult.thenAccept(elected -> { checkNotNull(elected); if (elected) { ctx.setState(Candidate.this, LEADER); } }).exceptionally(t -> { if (!electionResult.isCancelled()) { LOGGER.debug("Election failed with exception:", t); } return null; }); } @Inject  Candidate(RaftLog log, @RaftExecutor Fiber scheduler,
            @ElectionTimeout long electionTimeout, Client client); @Override void init(@Nonnull final RaftStateContext ctx); @Override void destroy(RaftStateContext ctx);  }