use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class ServerState method initRaftLog.
private static RaftLog initRaftLog(RaftGroupMemberId memberId, RaftServerImpl server, RaftStorage storage, Consumer<LogEntryProto> logConsumer, LongSupplier getSnapshotIndexFromStateMachine, RaftProperties prop) throws IOException {
final RaftLog log;
if (RaftServerConfigKeys.Log.useMemory(prop)) {
log = new MemoryRaftLog(memberId, getSnapshotIndexFromStateMachine, prop);
} else {
log = new SegmentedRaftLog(memberId, server, server.getStateMachine(), server::notifyTruncatedLogEntry, server::submitUpdateCommitEvent, storage, getSnapshotIndexFromStateMachine, prop);
}
log.open(log.getSnapshotIndex(), logConsumer);
return log;
}
use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class RaftSnapshotBaseTest method assertLeaderContent.
public static void assertLeaderContent(MiniRaftCluster cluster) throws Exception {
final RaftServer.Division leader = RaftTestUtil.waitForLeader(cluster);
final RaftLog leaderLog = leader.getRaftLog();
final long lastIndex = leaderLog.getLastEntryTermIndex().getIndex();
final LogEntryProto e = leaderLog.get(lastIndex);
Assert.assertTrue(e.hasMetadataEntry());
JavaUtils.attemptRepeatedly(() -> {
Assert.assertEquals(leaderLog.getLastCommittedIndex() - 1, e.getMetadataEntry().getCommitIndex());
return null;
}, 50, BaseTest.HUNDRED_MILLIS, "CheckMetadataEntry", LOG);
SimpleStateMachine4Testing simpleStateMachine = SimpleStateMachine4Testing.get(leader);
Assert.assertTrue("Is not notified as a leader", simpleStateMachine.isNotifiedAsLeader());
final LogEntryProto[] entries = simpleStateMachine.getContent();
long message = 0;
for (int i = 0; i < entries.length; i++) {
LOG.info("{}) {} {}", i, message, entries[i]);
if (entries[i].hasStateMachineLogEntry()) {
final SimpleMessage m = new SimpleMessage("m" + message++);
Assert.assertArrayEquals(m.getContent().toByteArray(), entries[i].getStateMachineLogEntry().getLogData().toByteArray());
}
}
}
use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class TestSegmentedRaftLog method checkEntries.
private void checkEntries(RaftLog raftLog, List<LogEntryProto> expected, int offset, int size) throws IOException {
if (size > 0) {
for (int i = offset; i < size + offset; i++) {
LogEntryProto entry = raftLog.get(expected.get(i).getIndex());
Assert.assertEquals(expected.get(i), entry);
}
final LogEntryHeader[] termIndices = raftLog.getEntries(expected.get(offset).getIndex(), expected.get(offset + size - 1).getIndex() + 1);
LogEntryProto[] entriesFromLog = Arrays.stream(termIndices).map(ti -> {
try {
return raftLog.get(ti.getIndex());
} catch (IOException e) {
throw new RuntimeException(e);
}
}).toArray(LogEntryProto[]::new);
LogEntryProto[] expectedArray = expected.subList(offset, offset + size).stream().toArray(LogEntryProto[]::new);
Assert.assertArrayEquals(expectedArray, entriesFromLog);
}
}
use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class ServerRestartTests method runTestRestartCommitIndex.
void runTestRestartCommitIndex(MiniRaftCluster cluster) throws Exception {
final SimpleMessage[] messages = SimpleMessage.create(100);
final List<CompletableFuture<Void>> futures = new ArrayList<>(messages.length);
for (int i = 0; i < messages.length; i++) {
final CompletableFuture<Void> f = new CompletableFuture<>();
futures.add(f);
final SimpleMessage m = messages[i];
new Thread(() -> {
try (final RaftClient client = cluster.createClient()) {
Assert.assertTrue(client.io().send(m).isSuccess());
} catch (IOException e) {
throw new IllegalStateException("Failed to send " + m, e);
}
f.complete(null);
}).start();
}
JavaUtils.allOf(futures).get();
final List<RaftPeerId> ids = new ArrayList<>();
final RaftServer.Division leader = cluster.getLeader();
final RaftLog leaderLog = leader.getRaftLog();
final RaftPeerId leaderId = leader.getId();
ids.add(leaderId);
RaftTestUtil.getStateMachineLogEntries(leaderLog);
// check that the last metadata entry is written to the log
JavaUtils.attempt(() -> assertLastLogEntry(leader), 20, HUNDRED_MILLIS, "leader last metadata entry", LOG);
final long lastIndex = leaderLog.getLastEntryTermIndex().getIndex();
LOG.info("{}: leader lastIndex={}", leaderId, lastIndex);
final LogEntryProto lastEntry = leaderLog.get(lastIndex);
LOG.info("{}: leader lastEntry entry[{}] = {}", leaderId, lastIndex, LogProtoUtils.toLogEntryString(lastEntry));
final long loggedCommitIndex = lastEntry.getMetadataEntry().getCommitIndex();
final LogEntryProto lastCommittedEntry = leaderLog.get(loggedCommitIndex);
LOG.info("{}: leader lastCommittedEntry = entry[{}] = {}", leaderId, loggedCommitIndex, LogProtoUtils.toLogEntryString(lastCommittedEntry));
final SimpleStateMachine4Testing leaderStateMachine = SimpleStateMachine4Testing.get(leader);
final TermIndex lastAppliedTermIndex = leaderStateMachine.getLastAppliedTermIndex();
LOG.info("{}: leader lastAppliedTermIndex = {}", leaderId, lastAppliedTermIndex);
// check follower logs
for (RaftServer.Division s : cluster.iterateDivisions()) {
if (!s.getId().equals(leaderId)) {
ids.add(s.getId());
JavaUtils.attempt(() -> RaftTestUtil.assertSameLog(leaderLog, s.getRaftLog()), 10, HUNDRED_MILLIS, "assertRaftLog-" + s.getId(), LOG);
}
}
// take snapshot and truncate last (metadata) entry
leaderStateMachine.takeSnapshot();
leaderLog.truncate(lastIndex);
// kill all servers
ids.forEach(cluster::killServer);
// Restart and kill servers one by one so that they won't talk to each other.
for (RaftPeerId id : ids) {
cluster.restartServer(id, false);
final RaftServer.Division server = cluster.getDivision(id);
final RaftLog raftLog = server.getRaftLog();
JavaUtils.attemptRepeatedly(() -> {
Assert.assertTrue(raftLog.getLastCommittedIndex() >= loggedCommitIndex);
return null;
}, 10, HUNDRED_MILLIS, id + "(commitIndex >= loggedCommitIndex)", LOG);
JavaUtils.attemptRepeatedly(() -> {
Assert.assertTrue(server.getInfo().getLastAppliedIndex() >= loggedCommitIndex);
return null;
}, 10, HUNDRED_MILLIS, id + "(lastAppliedIndex >= loggedCommitIndex)", LOG);
LOG.info("{}: commitIndex={}, lastAppliedIndex={}", id, raftLog.getLastCommittedIndex(), server.getInfo().getLastAppliedIndex());
cluster.killServer(id);
}
}
use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class ServerRestartTests method runTestRestartWithCorruptedLogEntry.
private void runTestRestartWithCorruptedLogEntry(CLUSTER cluster) throws Exception {
// this is the only server
final RaftServer.Division leader = RaftTestUtil.waitForLeader(cluster);
final RaftPeerId id = leader.getId();
// send a few messages
final SimpleMessage[] messages = SimpleMessage.create(10);
final SimpleMessage lastMessage = messages[messages.length - 1];
try (final RaftClient client = cluster.createClient()) {
for (SimpleMessage m : messages) {
Assert.assertTrue(client.io().send(m).isSuccess());
}
// assert that the last message exists
Assert.assertTrue(client.io().sendReadOnly(lastMessage).isSuccess());
}
final RaftLog log = leader.getRaftLog();
final long size = TestSegmentedRaftLog.getOpenSegmentSize(log);
leader.getRaftServer().close();
// corrupt the log
final File openLogFile = JavaUtils.attemptRepeatedly(() -> getOpenLogFile(leader), 10, HUNDRED_MILLIS, id + "-getOpenLogFile", LOG);
try (final RandomAccessFile raf = new RandomAccessFile(openLogFile, "rw")) {
final long mid = size / 2;
raf.seek(mid);
for (long i = mid; i < size; i++) {
raf.write(0);
}
}
// after the log is corrupted and the server is restarted, the last entry should no longer exist.
cluster.restartServer(id, false);
testFailureCase("last-entry-not-found", () -> {
try (final RaftClient client = cluster.createClient()) {
client.io().sendReadOnly(lastMessage);
}
}, StateMachineException.class, IndexOutOfBoundsException.class);
}
Aggregations