use of org.apache.ratis.protocol.RaftClientReply in project incubator-ratis by apache.
the class WatchRequestTests method runTestWatchRequestAsync.
static void runTestWatchRequestAsync(TestParameters p) throws Exception {
final Logger LOG = p.log;
final MiniRaftCluster cluster = p.cluster;
final int numMessages = p.numMessages;
// blockStartTransaction of the leader so that no transaction can be committed MAJORITY
final RaftServer.Division leader = cluster.getLeader();
LOG.info("block leader {}", leader.getId());
SimpleStateMachine4Testing.get(leader).blockStartTransaction();
// blockFlushStateMachineData a follower so that no transaction can be ALL_COMMITTED
final List<RaftServer.Division> followers = cluster.getFollowers();
final RaftServer.Division blockedFollower = followers.get(ThreadLocalRandom.current().nextInt(followers.size()));
LOG.info("block follower {}", blockedFollower.getId());
SimpleStateMachine4Testing.get(blockedFollower).blockFlushStateMachineData();
// send a message
final List<CompletableFuture<RaftClientReply>> replies = new ArrayList<>();
final List<CompletableFuture<WatchReplies>> watches = new ArrayList<>();
p.sendRequests(replies, watches);
Assert.assertEquals(numMessages, replies.size());
Assert.assertEquals(numMessages, watches.size());
// since leader is blocked, nothing can be done.
TimeUnit.SECONDS.sleep(1);
assertNotDone(replies);
assertNotDone(watches);
// unblock leader so that the transaction can be committed.
SimpleStateMachine4Testing.get(leader).unblockStartTransaction();
LOG.info("unblock leader {}", leader.getId());
checkMajority(replies, watches, LOG);
Assert.assertEquals(numMessages, watches.size());
// but not replicated/committed to all.
TimeUnit.SECONDS.sleep(1);
assertNotDone(watches.stream().map(CompletableFuture::join).map(w -> w.all));
assertNotDone(watches.stream().map(CompletableFuture::join).map(w -> w.allCommitted));
// unblock follower so that the transaction can be replicated and committed to all.
LOG.info("unblock follower {}", blockedFollower.getId());
SimpleStateMachine4Testing.get(blockedFollower).unblockFlushStateMachineData();
checkAll(watches, LOG);
}
use of org.apache.ratis.protocol.RaftClientReply in project incubator-ratis by apache.
the class WatchRequestTests method checkMajority.
static void checkMajority(List<CompletableFuture<RaftClientReply>> replies, List<CompletableFuture<WatchReplies>> watches, Logger LOG) throws Exception {
for (int i = 0; i < replies.size(); i++) {
final RaftClientReply reply = replies.get(i).get(GET_TIMEOUT_SECOND, TimeUnit.SECONDS);
LOG.info("checkMajority {}: receive {}", i, reply);
final long logIndex = reply.getLogIndex();
Assert.assertTrue(reply.isSuccess());
final WatchReplies watchReplies = watches.get(i).get(GET_TIMEOUT_SECOND, TimeUnit.SECONDS);
Assert.assertEquals(logIndex, watchReplies.logIndex);
final RaftClientReply watchMajorityReply = watchReplies.getMajority();
Assert.assertTrue(watchMajorityReply.isSuccess());
final RaftClientReply watchMajorityCommittedReply = watchReplies.getMajorityCommitted();
Assert.assertTrue(watchMajorityCommittedReply.isSuccess());
{
// check commit infos
final Collection<CommitInfoProto> commitInfos = watchMajorityCommittedReply.getCommitInfos();
final String message = "logIndex=" + logIndex + ", " + ProtoUtils.toString(commitInfos);
Assert.assertEquals(NUM_SERVERS, commitInfos.size());
// One follower has not committed, so min must be less than logIndex
final long min = commitInfos.stream().map(CommitInfoProto::getCommitIndex).min(Long::compare).get();
Assert.assertTrue(message, logIndex > min);
// All other followers have committed
commitInfos.stream().map(CommitInfoProto::getCommitIndex).sorted(Long::compare).skip(1).forEach(ci -> Assert.assertTrue(message, logIndex <= ci));
}
}
}
use of org.apache.ratis.protocol.RaftClientReply in project incubator-ratis by apache.
the class RaftBasicTests method runTestBasicAppendEntries.
static void runTestBasicAppendEntries(boolean async, boolean killLeader, int numMessages, MiniRaftCluster cluster, Logger LOG) throws Exception {
LOG.info("runTestBasicAppendEntries: async? {}, killLeader={}, numMessages={}", async, killLeader, numMessages);
for (RaftServer s : cluster.getServers()) {
cluster.restartServer(s.getId(), false);
}
RaftServer.Division leader = waitForLeader(cluster);
final long term = leader.getInfo().getCurrentTerm();
final CompletableFuture<Void> killAndRestartFollower = killAndRestartServer(cluster.getFollowers().get(0).getId(), 0, 1000, cluster, LOG);
final CompletableFuture<Void> killAndRestartLeader;
if (killLeader) {
LOG.info("killAndRestart leader " + leader.getId());
killAndRestartLeader = killAndRestartServer(leader.getId(), 2000, 4000, cluster, LOG);
} else {
killAndRestartLeader = CompletableFuture.completedFuture(null);
}
LOG.info(cluster.printServers());
final SimpleMessage[] messages = SimpleMessage.create(numMessages);
try (final RaftClient client = cluster.createClient()) {
final AtomicInteger asyncReplyCount = new AtomicInteger();
final CompletableFuture<Void> f = new CompletableFuture<>();
for (SimpleMessage message : messages) {
if (async) {
client.async().send(message).thenAcceptAsync(reply -> {
if (!reply.isSuccess()) {
f.completeExceptionally(new AssertionError("Failed with reply " + reply));
} else if (asyncReplyCount.incrementAndGet() == messages.length) {
f.complete(null);
}
});
} else {
final RaftClientReply reply = client.io().send(message);
Assert.assertTrue(reply.isSuccess());
}
}
if (async) {
f.join();
Assert.assertEquals(messages.length, asyncReplyCount.get());
}
}
Thread.sleep(cluster.getTimeoutMax().toIntExact(TimeUnit.MILLISECONDS) + 100);
LOG.info(cluster.printAllLogs());
killAndRestartFollower.join();
killAndRestartLeader.join();
final List<RaftServer.Division> divisions = cluster.getServerAliveStream().collect(Collectors.toList());
for (RaftServer.Division impl : divisions) {
JavaUtils.attempt(() -> RaftTestUtil.assertLogEntries(impl, term, messages), 5, TimeDuration.valueOf(1, TimeUnit.SECONDS), impl.getId() + " assertLogEntries", LOG);
}
}
use of org.apache.ratis.protocol.RaftClientReply in project incubator-ratis by apache.
the class InstallSnapshotNotificationTests method testAddNewFollowers.
private void testAddNewFollowers(CLUSTER cluster) throws Exception {
leaderSnapshotInfoRef.set(null);
final List<LogSegmentPath> logs;
int i = 0;
try {
RaftTestUtil.waitForLeader(cluster);
final RaftPeerId leaderId = cluster.getLeader().getId();
try (final RaftClient client = cluster.createClient(leaderId)) {
for (; i < SNAPSHOT_TRIGGER_THRESHOLD * 2 - 1; i++) {
RaftClientReply reply = client.io().send(new RaftTestUtil.SimpleMessage("m" + i));
Assert.assertTrue(reply.isSuccess());
}
}
// wait for the snapshot to be done
final RaftServer.Division leader = cluster.getLeader();
final long nextIndex = leader.getRaftLog().getNextIndex();
LOG.info("nextIndex = {}", nextIndex);
final List<File> snapshotFiles = RaftSnapshotBaseTest.getSnapshotFiles(cluster, nextIndex - SNAPSHOT_TRIGGER_THRESHOLD, nextIndex);
JavaUtils.attemptRepeatedly(() -> {
Assert.assertTrue(snapshotFiles.stream().anyMatch(RaftSnapshotBaseTest::exists));
return null;
}, 10, ONE_SECOND, "snapshotFile.exist", LOG);
logs = LogSegmentPath.getLogSegmentPaths(leader.getRaftStorage());
} finally {
cluster.shutdown();
}
// delete the log segments from the leader
LOG.info("Delete logs {}", logs);
for (LogSegmentPath path : logs) {
// the log may be already puged
FileUtils.deleteFully(path.getPath());
}
// restart the peer
LOG.info("Restarting the cluster");
cluster.restart(false);
try {
RaftSnapshotBaseTest.assertLeaderContent(cluster);
// generate some more traffic
try (final RaftClient client = cluster.createClient(cluster.getLeader().getId())) {
Assert.assertTrue(client.io().send(new RaftTestUtil.SimpleMessage("m" + i)).isSuccess());
}
final SnapshotInfo leaderSnapshotInfo = cluster.getLeader().getStateMachine().getLatestSnapshot();
final boolean set = leaderSnapshotInfoRef.compareAndSet(null, leaderSnapshotInfo);
Assert.assertTrue(set);
// add two more peers
final MiniRaftCluster.PeerChanges change = cluster.addNewPeers(2, true, true);
// trigger setConfiguration
cluster.setConfiguration(change.allPeersInNewConf);
RaftServerTestUtil.waitAndCheckNewConf(cluster, change.allPeersInNewConf, 0, null);
// leader snapshot.
for (RaftServer.Division follower : cluster.getFollowers()) {
Assert.assertEquals(leaderSnapshotInfo.getIndex(), RaftServerTestUtil.getLatestInstalledSnapshotIndex(follower));
}
// restart the peer and check if it can correctly handle conf change
cluster.restartServer(cluster.getLeader().getId(), false);
RaftSnapshotBaseTest.assertLeaderContent(cluster);
} finally {
cluster.shutdown();
}
}
use of org.apache.ratis.protocol.RaftClientReply in project incubator-ratis by apache.
the class InstallSnapshotNotificationTests method testRestartFollower.
private void testRestartFollower(CLUSTER cluster) throws Exception {
leaderSnapshotInfoRef.set(null);
int i = 0;
final RaftServer.Division leader = RaftTestUtil.waitForLeader(cluster);
final RaftPeerId leaderId = leader.getId();
try (final RaftClient client = cluster.createClient(leaderId)) {
for (; i < SNAPSHOT_TRIGGER_THRESHOLD * 2 - 1; i++) {
final RaftClientReply reply = client.io().send(new RaftTestUtil.SimpleMessage("m" + i));
Assert.assertTrue(reply.isSuccess());
}
}
// wait for the snapshot to be done
final long oldLeaderNextIndex = leader.getRaftLog().getNextIndex();
{
LOG.info("{}: oldLeaderNextIndex = {}", leaderId, oldLeaderNextIndex);
final List<File> snapshotFiles = RaftSnapshotBaseTest.getSnapshotFiles(cluster, oldLeaderNextIndex - SNAPSHOT_TRIGGER_THRESHOLD, oldLeaderNextIndex);
JavaUtils.attemptRepeatedly(() -> {
Assert.assertTrue(snapshotFiles.stream().anyMatch(RaftSnapshotBaseTest::exists));
return null;
}, 10, ONE_SECOND, "snapshotFile.exist", LOG);
}
final RaftPeerId followerId = cluster.getFollowers().get(0).getId();
cluster.killServer(followerId);
// generate some more traffic
try (final RaftClient client = cluster.createClient(leader.getId())) {
Assert.assertTrue(client.io().send(new RaftTestUtil.SimpleMessage("m" + i)).isSuccess());
}
FIVE_SECONDS.sleep();
cluster.restartServer(followerId, false);
final RaftServer.Division follower = cluster.getDivision(followerId);
JavaUtils.attempt(() -> {
final long newLeaderNextIndex = leader.getRaftLog().getNextIndex();
LOG.info("{}: newLeaderNextIndex = {}", leaderId, newLeaderNextIndex);
Assert.assertTrue(newLeaderNextIndex > oldLeaderNextIndex);
Assert.assertEquals(newLeaderNextIndex, follower.getRaftLog().getNextIndex());
}, 10, ONE_SECOND, "followerNextIndex", LOG);
}
Aggregations