ServerState(RaftPeerId id, RaftGroup group, RaftProperties prop, RaftServerImpl server, StateMachine stateMachine) throws IOException { this.selfId = id; this.server = server; RaftConfiguration initialConf = RaftConfiguration.newBuilder() .setConf(group.getPeers()).build(); configurationManager = new ConfigurationManager(initialConf); LOG.info("{}: {}", id, configurationManager); // use full uuid string to create a subdirectory final File dir = chooseStorageDir(RaftServerConfigKeys.storageDirs(prop), group.getGroupId().getUuid().toString()); storage = new RaftStorage(dir, RaftServerConstants.StartupOption.REGULAR); snapshotManager = new SnapshotManager(storage, id); long lastApplied = initStatemachine(stateMachine, group.getGroupId()); // On start the leader is null, start the clock now leaderId = null; this.lastNoLeaderTime = Timestamp.currentTime(); this.leaderElectionTimeoutMs = RaftServerConfigKeys.leaderElectionTimeout(prop).toIntExact(TimeUnit.MILLISECONDS); // we cannot apply log entries to the state machine in this step, since we // do not know whether the local log entries have been committed. log = initLog(id, prop, lastApplied, this::setRaftConf); RaftLog.Metadata metadata = log.loadMetadata(); currentTerm = metadata.getTerm(); votedFor = metadata.getVotedFor(); stateMachineUpdater = new StateMachineUpdater(stateMachine, server, log, lastApplied, prop); }
@Test public void testLeaderElectionDetection() throws Exception { RaftTestUtil.waitForLeader(cluster); long leaderElectionTimeout = RaftServerConfigKeys. leaderElectionTimeout(cluster.getProperties()).toIntExact(TimeUnit.MILLISECONDS); RaftServerImpl healthyFollower = cluster.getFollowers().get(1); RaftServerImpl failedFollower = cluster.getFollowers().get(0); // fail the leader and one of the followers to that quorum is not present // for next leader election to succeed. cluster.killServer(failedFollower.getId()); cluster.killServer(cluster.getLeader().getId()); // Wait to ensure that leader election is triggered and also state machine callback is triggered Thread.sleep( leaderElectionTimeout * 2); RaftProtos.RoleInfoProto roleInfoProto = SimpleStateMachine4Testing.get(healthyFollower).getLeaderElectionTimeoutInfo(); Assert.assertNotNull(roleInfoProto); Assert.assertEquals(roleInfoProto.getRole(), RaftProtos.RaftPeerRole.CANDIDATE); Assert.assertTrue(roleInfoProto.getCandidateInfo().getLastLeaderElapsedTimeMs() > leaderElectionTimeout); } }