use of org.apache.ratis.proto.RaftProtos.CommitInfoProto in project incubator-ratis by apache.
the class WatchRequestTests method checkAll.
static void checkAll(List<CompletableFuture<WatchReplies>> watches, Logger LOG) throws Exception {
for (int i = 0; i < watches.size(); i++) {
final WatchReplies watchReplies = watches.get(i).get(GET_TIMEOUT_SECOND, TimeUnit.SECONDS);
final long logIndex = watchReplies.logIndex;
LOG.info("checkAll {}: logIndex={}", i, logIndex);
final RaftClientReply watchAllReply = watchReplies.getAll();
Assert.assertTrue(watchAllReply.isSuccess());
final RaftClientReply watchAllCommittedReply = watchReplies.getAllCommitted();
Assert.assertTrue(watchAllCommittedReply.isSuccess());
{
// check commit infos
final Collection<CommitInfoProto> commitInfos = watchAllCommittedReply.getCommitInfos();
final String message = "logIndex=" + logIndex + ", " + ProtoUtils.toString(commitInfos);
Assert.assertEquals(NUM_SERVERS, commitInfos.size());
commitInfos.forEach(info -> Assert.assertTrue(message, logIndex <= info.getCommitIndex()));
}
}
}
use of org.apache.ratis.proto.RaftProtos.CommitInfoProto in project incubator-ratis by apache.
the class RaftAsyncTests method runTestStaleReadAsync.
void runTestStaleReadAsync(CLUSTER cluster) throws Exception {
final int numMesssages = 10;
try (RaftClient client = cluster.createClient()) {
RaftTestUtil.waitForLeader(cluster);
// submit some messages
final List<CompletableFuture<RaftClientReply>> futures = new ArrayList<>();
for (int i = 0; i < numMesssages; i++) {
final String s = "" + i;
LOG.info("sendAsync " + s);
futures.add(client.async().send(new SimpleMessage(s)));
}
Assert.assertEquals(numMesssages, futures.size());
final List<RaftClientReply> replies = new ArrayList<>();
for (CompletableFuture<RaftClientReply> f : futures) {
final RaftClientReply r = f.join();
Assert.assertTrue(r.isSuccess());
replies.add(r);
}
futures.clear();
// Use a follower with the max commit index
final RaftClientReply lastWriteReply = replies.get(replies.size() - 1);
final RaftPeerId leader = lastWriteReply.getServerId();
LOG.info("leader = " + leader);
final Collection<CommitInfoProto> commitInfos = lastWriteReply.getCommitInfos();
LOG.info("commitInfos = " + commitInfos);
final CommitInfoProto followerCommitInfo = commitInfos.stream().filter(info -> !RaftPeerId.valueOf(info.getServer().getId()).equals(leader)).max(Comparator.comparing(CommitInfoProto::getCommitIndex)).get();
final RaftPeerId follower = RaftPeerId.valueOf(followerCommitInfo.getServer().getId());
final long followerCommitIndex = followerCommitInfo.getCommitIndex();
LOG.info("max follower = {}, commitIndex = {}", follower, followerCommitIndex);
// test a failure case
testFailureCaseAsync("sendStaleReadAsync(..) with a larger commit index", () -> client.async().sendStaleRead(new SimpleMessage("" + Long.MAX_VALUE), followerCommitInfo.getCommitIndex(), follower), StateMachineException.class, IndexOutOfBoundsException.class);
// test sendStaleReadAsync
for (int i = 0; i < numMesssages; i++) {
final RaftClientReply reply = replies.get(i);
final String query = "" + i;
LOG.info("query=" + query + ", reply=" + reply);
final Message message = new SimpleMessage(query);
final CompletableFuture<RaftClientReply> readFuture = client.async().sendReadOnly(message);
futures.add(readFuture.thenCompose(r -> {
if (reply.getLogIndex() <= followerCommitIndex) {
LOG.info("sendStaleReadAsync, query=" + query);
return client.async().sendStaleRead(message, followerCommitIndex, follower);
} else {
return CompletableFuture.completedFuture(null);
}
}).thenApply(staleReadReply -> {
if (staleReadReply == null) {
return null;
}
final ByteString expected = readFuture.join().getMessage().getContent();
final ByteString computed = staleReadReply.getMessage().getContent();
try {
LOG.info("query " + query + " returns " + LogEntryProto.parseFrom(expected).getStateMachineLogEntry().getLogData().toStringUtf8());
} catch (InvalidProtocolBufferException e) {
throw new CompletionException(e);
}
Assert.assertEquals("log entry mismatch for query=" + query, expected, computed);
return null;
}));
}
JavaUtils.allOf(futures).join();
}
}
use of org.apache.ratis.proto.RaftProtos.CommitInfoProto in project incubator-ratis by apache.
the class StateMachineUpdater method takeSnapshot.
private void takeSnapshot() {
final long i;
try {
Timer.Context takeSnapshotTimerContext = stateMachineMetrics.getTakeSnapshotTimer().time();
i = stateMachine.takeSnapshot();
takeSnapshotTimerContext.stop();
server.getSnapshotRequestHandler().completeTakingSnapshot(i);
final long lastAppliedIndex = getLastAppliedIndex();
if (i > lastAppliedIndex) {
throw new StateMachineException("Bug in StateMachine: snapshot index = " + i + " > appliedIndex = " + lastAppliedIndex + "; StateMachine class=" + stateMachine.getClass().getName() + ", stateMachine=" + stateMachine);
}
stateMachine.getStateMachineStorage().cleanupOldSnapshots(snapshotRetentionPolicy);
} catch (IOException e) {
LOG.error(name + ": Failed to take snapshot", e);
return;
}
if (i >= 0) {
LOG.info("{}: Took a snapshot at index {}", name, i);
snapshotIndex.updateIncreasingly(i, infoIndexChange);
final long purgeIndex;
if (purgeUptoSnapshotIndex) {
// We can purge up to snapshot index even if all the peers do not have
// commitIndex up to this snapshot index.
purgeIndex = i;
} else {
final LongStream commitIndexStream = server.getCommitInfos().stream().mapToLong(CommitInfoProto::getCommitIndex);
purgeIndex = LongStream.concat(LongStream.of(i), commitIndexStream).min().orElse(i);
}
raftLog.purge(purgeIndex);
}
}
use of org.apache.ratis.proto.RaftProtos.CommitInfoProto in project incubator-ratis by apache.
the class LeaderStateImpl method stop.
void stop() {
this.running = false;
// do not interrupt event processor since it may be in the middle of logSync
senders.forEach(LogAppender::stop);
final NotLeaderException nle = server.generateNotLeaderException();
final Collection<CommitInfoProto> commitInfos = server.getCommitInfos();
try {
final Collection<TransactionContext> transactions = pendingRequests.sendNotLeaderResponses(nle, commitInfos);
server.getStateMachine().leaderEvent().notifyNotLeader(transactions);
watchRequests.failWatches(nle);
} catch (IOException e) {
LOG.warn("{}: Caught exception in sendNotLeaderResponses", this, e);
}
messageStreamRequests.clear();
server.getServerRpc().notifyNotLeader(server.getMemberId().getGroupId());
logAppenderMetrics.unregister();
raftServerMetrics.unregister();
pendingRequests.close();
}
use of org.apache.ratis.proto.RaftProtos.CommitInfoProto 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));
}
}
}
Aggregations