use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class RaftBasicTests method runTestOldLeaderCommit.
void runTestOldLeaderCommit(CLUSTER cluster) throws Exception {
final RaftServer.Division leader = waitForLeader(cluster);
final RaftPeerId leaderId = leader.getId();
final long term = leader.getInfo().getCurrentTerm();
final List<RaftServer.Division> followers = cluster.getFollowers();
final List<RaftServer.Division> followersToSendLog = followers.subList(0, followers.size() / 2);
for (int i = followers.size() / 2; i < NUM_SERVERS - 1; i++) {
cluster.killServer(followers.get(i).getId());
}
SimpleMessage[] messages = SimpleMessage.create(1);
RaftTestUtil.sendMessageInNewThread(cluster, leaderId, messages);
Thread.sleep(cluster.getTimeoutMax().toLong(TimeUnit.MILLISECONDS) + 100);
for (RaftServer.Division followerToSendLog : followersToSendLog) {
RaftLog followerLog = followerToSendLog.getRaftLog();
Assert.assertTrue(RaftTestUtil.logEntriesContains(followerLog, messages));
}
LOG.info(String.format("killing old leader: %s", leaderId.toString()));
cluster.killServer(leaderId);
for (int i = followers.size() / 2; i < NUM_SERVERS - 1; i++) {
final RaftPeerId followerId = followers.get(i).getId();
LOG.info(String.format("restarting follower: %s", followerId));
cluster.restartServer(followerId, false);
}
Thread.sleep(cluster.getTimeoutMax().toLong(TimeUnit.MILLISECONDS) * 5);
// confirm the server with log is elected as new leader.
final RaftPeerId newLeaderId = waitForLeader(cluster).getId();
Set<RaftPeerId> followersToSendLogIds = followersToSendLog.stream().map(f -> f.getId()).collect(Collectors.toSet());
Assert.assertTrue(followersToSendLogIds.contains(newLeaderId));
cluster.getServerAliveStream().map(RaftServer.Division::getRaftLog).forEach(log -> RaftTestUtil.assertLogEntries(log, term, messages));
}
use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class RaftTestUtil method assertLogEntries.
static void assertLogEntries(RaftServer.Division server, long expectedTerm, SimpleMessage... expectedMessages) {
LOG.info("checking raft log for {}", server.getMemberId());
final RaftLog log = server.getRaftLog();
try {
RaftTestUtil.assertLogEntries(log, expectedTerm, expectedMessages);
} catch (AssertionError e) {
LOG.error("Unexpected raft log in {}", server.getMemberId(), e);
throw e;
}
}
use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class ServerRestartTests method runTestRestartFollower.
void runTestRestartFollower(MiniRaftCluster cluster) throws Exception {
RaftTestUtil.waitForLeader(cluster);
final RaftPeerId leaderId = cluster.getLeader().getId();
// write some messages
final AtomicInteger messageCount = new AtomicInteger();
final Supplier<Message> newMessage = () -> new SimpleMessage("m" + messageCount.getAndIncrement());
writeSomething(newMessage, cluster);
// restart a follower
RaftPeerId followerId = cluster.getFollowers().get(0).getId();
LOG.info("Restart follower {}", followerId);
cluster.restartServer(followerId, false);
// write some more messages
writeSomething(newMessage, cluster);
final int truncatedMessageIndex = messageCount.get() - 1;
final long leaderLastIndex = cluster.getLeader().getRaftLog().getLastEntryTermIndex().getIndex();
// make sure the restarted follower can catchup
final RaftServer.Division followerState = cluster.getDivision(followerId);
JavaUtils.attemptRepeatedly(() -> {
Assert.assertTrue(followerState.getInfo().getLastAppliedIndex() >= leaderLastIndex);
return null;
}, 10, ONE_SECOND, "follower catchup", LOG);
// make sure the restarted peer's log segments is correct
final RaftServer.Division follower = cluster.restartServer(followerId, false);
final RaftLog followerLog = follower.getRaftLog();
final long followerLastIndex = followerLog.getLastEntryTermIndex().getIndex();
Assert.assertTrue(followerLastIndex >= leaderLastIndex);
final File followerOpenLogFile = getOpenLogFile(follower);
final File leaderOpenLogFile = getOpenLogFile(cluster.getDivision(leaderId));
// shutdown all servers
for (RaftServer s : cluster.getServers()) {
s.close();
}
// truncate log and
assertTruncatedLog(followerId, followerOpenLogFile, followerLastIndex, cluster);
assertTruncatedLog(leaderId, leaderOpenLogFile, leaderLastIndex, cluster);
// restart and write something.
cluster.restart(false);
writeSomething(newMessage, cluster);
// restart again and check messages.
cluster.restart(false);
try (final RaftClient client = cluster.createClient()) {
for (int i = 0; i < messageCount.get(); i++) {
if (i != truncatedMessageIndex) {
final Message m = new SimpleMessage("m" + i);
final RaftClientReply reply = client.io().sendReadOnly(m);
Assert.assertTrue(reply.isSuccess());
LOG.info("query {}: {} {}", m, reply, LogEntryProto.parseFrom(reply.getMessage().getContent()));
}
}
}
}
use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class TestRaftWithGrpc method runTestUpdateViaHeartbeat.
void runTestUpdateViaHeartbeat(MiniRaftClusterWithGrpc cluster) throws Exception {
waitForLeader(cluster);
try (final RaftClient client = cluster.createClient()) {
// block append requests
cluster.getServerAliveStream().filter(impl -> !impl.getInfo().isLeader()).map(SimpleStateMachine4Testing::get).forEach(SimpleStateMachine4Testing::blockWriteStateMachineData);
CompletableFuture<RaftClientReply> replyFuture = client.async().send(new RaftTestUtil.SimpleMessage("abc"));
TimeDuration.valueOf(5, TimeUnit.SECONDS).sleep();
// replyFuture should not be completed until append request is unblocked.
Assert.assertFalse(replyFuture.isDone());
// unblock append request.
cluster.getServerAliveStream().filter(impl -> !impl.getInfo().isLeader()).map(SimpleStateMachine4Testing::get).forEach(SimpleStateMachine4Testing::unblockWriteStateMachineData);
final RaftLog leaderLog = cluster.getLeader().getRaftLog();
// The entries have been appended in the followers
// although the append entry timed out at the leader
cluster.getServerAliveStream().filter(impl -> !impl.getInfo().isLeader()).forEach(raftServer -> JavaUtils.runAsUnchecked(() -> JavaUtils.attempt(() -> {
final long leaderNextIndex = leaderLog.getNextIndex();
final LogEntryHeader[] leaderEntries = leaderLog.getEntries(0, Long.MAX_VALUE);
final RaftLog followerLog = raftServer.getRaftLog();
Assert.assertEquals(leaderNextIndex, followerLog.getNextIndex());
final LogEntryHeader[] serverEntries = followerLog.getEntries(0, Long.MAX_VALUE);
Assert.assertArrayEquals(serverEntries, leaderEntries);
}, 10, HUNDRED_MILLIS, "assertRaftLog-" + raftServer.getId(), LOG)));
// Wait for heartbeats from leader to be received by followers
Thread.sleep(500);
RaftServerTestUtil.getLogAppenders(cluster.getLeader()).forEach(logAppender -> JavaUtils.runAsUnchecked(() -> JavaUtils.attempt(() -> {
final long leaderNextIndex = leaderLog.getNextIndex();
// FollowerInfo in the leader state should have updated next and match index.
final long followerMatchIndex = logAppender.getFollower().getMatchIndex();
Assert.assertTrue(followerMatchIndex >= leaderNextIndex - 1);
Assert.assertEquals(followerMatchIndex + 1, logAppender.getFollower().getNextIndex());
}, 10, HUNDRED_MILLIS, "assertRaftLog-" + logAppender.getFollower(), LOG)));
}
}
use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class RaftStateMachineExceptionTests method runTestRetryOnStateMachineException.
private void runTestRetryOnStateMachineException(CLUSTER cluster) throws Exception {
RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
cluster.getLeaderAndSendFirstMessage(true);
final long oldLastApplied = cluster.getLeader().getInfo().getLastAppliedIndex();
try (final RaftClient client = cluster.createClient(leaderId)) {
final RaftClientRpc rpc = client.getClientRpc();
final long callId = 999;
final SimpleMessage message = new SimpleMessage("message");
final RaftClientRequest r = cluster.newRaftClientRequest(client.getId(), leaderId, callId, message);
RaftClientReply reply = rpc.sendRequest(r);
Assert.assertFalse(reply.isSuccess());
Assert.assertNotNull(reply.getStateMachineException());
// retry with the same callId
for (int i = 0; i < 5; i++) {
reply = rpc.sendRequest(r);
Assert.assertEquals(client.getId(), reply.getClientId());
Assert.assertEquals(callId, reply.getCallId());
Assert.assertFalse(reply.isSuccess());
Assert.assertNotNull(reply.getStateMachineException());
}
for (RaftServer.Division server : cluster.iterateDivisions()) {
LOG.info("check server " + server.getId());
JavaUtils.attemptRepeatedly(() -> {
Assert.assertNotNull(RetryCacheTestUtil.get(server, client.getId(), callId));
return null;
}, 5, BaseTest.ONE_SECOND, "GetRetryEntry", LOG);
final RaftLog log = server.getRaftLog();
RaftTestUtil.logEntriesContains(log, oldLastApplied + 1, log.getNextIndex(), message);
}
cluster.shutdown();
}
}
Aggregations