public void testCandidateTransitionsToFollowerOnRejection() throws Throwable {
    serverState.onStateChange(
        state -> {
          if (state == RaftServer.State.FOLLOWER) resume();
        });

    runOnServer(
        () -> {
          for (MemberState member : serverState.getCluster().getActiveMembers()) {
            Server server = transport.server();
            server
                .listen(
                    member.getAddress(),
                    c -> {
                      c.handler(
                          VoteRequest.class,
                          request ->
                              CompletableFuture.completedFuture(
                                  VoteResponse.builder().withTerm(2).withVoted(false).build()));
                    })
                .thenRunAsync(this::resume);
          }
        });

    await(1000, serverState.getCluster().getActiveMembers().size());

    runOnServer(
        () -> {
          int self = serverState.getAddress().hashCode();
          serverState.setTerm(1);

          state.startElection();

          assertEquals(serverState.getTerm(), 2L);
          assertEquals(serverState.getLastVotedFor(), self);
        });
    await(1000);
  }
Exemple #2
0
 @Override
 public CompletableFuture<Void> close() {
   return local.close().thenCompose(v -> remote.close());
 }
Exemple #3
0
 @Override
 public CompletableFuture<Void> listen(Address address, Consumer<Connection> listener) {
   Assert.notNull(address, "address");
   Assert.notNull(listener, "listener");
   return local.listen(address, listener).thenCompose(v -> remote.listen(address, listener));
 }