use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class ServerRestartTests method assertLastLogEntry.
static void assertLastLogEntry(RaftServer.Division server) throws RaftLogIOException {
final RaftLog raftLog = server.getRaftLog();
final long lastIndex = raftLog.getLastEntryTermIndex().getIndex();
final LogEntryProto lastEntry = raftLog.get(lastIndex);
Assert.assertTrue(lastEntry.hasMetadataEntry());
final long loggedCommitIndex = lastEntry.getMetadataEntry().getCommitIndex();
final LogEntryProto lastCommittedEntry = raftLog.get(loggedCommitIndex);
Assert.assertTrue(lastCommittedEntry.hasStateMachineLogEntry());
final SimpleStateMachine4Testing leaderStateMachine = SimpleStateMachine4Testing.get(server);
final TermIndex lastAppliedTermIndex = leaderStateMachine.getLastAppliedTermIndex();
Assert.assertEquals(lastCommittedEntry.getTerm(), lastAppliedTermIndex.getTerm());
Assert.assertTrue(lastCommittedEntry.getIndex() <= lastAppliedTermIndex.getIndex());
}
use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class TestSegmentedRaftLog method testLoadLogSegments.
@Test
public void testLoadLogSegments() throws Exception {
// first generate log files
List<SegmentRange> ranges = prepareRanges(0, 5, 100, 0);
LogEntryProto[] entries = prepareLog(ranges);
// create RaftLog object and load log file
try (SegmentedRaftLog raftLog = newSegmentedRaftLog()) {
raftLog.open(RaftLog.INVALID_LOG_INDEX, null);
// check if log entries are loaded correctly
for (LogEntryProto e : entries) {
LogEntryProto entry = raftLog.get(e.getIndex());
Assert.assertEquals(e, entry);
}
final LogEntryHeader[] termIndices = raftLog.getEntries(0, 500);
LogEntryProto[] entriesFromLog = Arrays.stream(termIndices).map(ti -> {
try {
return raftLog.get(ti.getIndex());
} catch (IOException e) {
throw new RuntimeException(e);
}
}).toArray(LogEntryProto[]::new);
Assert.assertArrayEquals(entries, entriesFromLog);
Assert.assertEquals(entries[entries.length - 1], getLastEntry(raftLog));
final RatisMetricRegistry metricRegistryForLogWorker = RaftLogMetricsBase.getLogWorkerMetricRegistry(memberId);
Timer raftLogSegmentLoadLatencyTimer = metricRegistryForLogWorker.timer("segmentLoadLatency");
assertTrue(raftLogSegmentLoadLatencyTimer.getMeanRate() > 0);
Timer raftLogReadLatencyTimer = metricRegistryForLogWorker.timer("readEntryLatency");
assertTrue(raftLogReadLatencyTimer.getMeanRate() > 0);
}
}
use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class RaftReconfigurationBaseTest method runTestKillLeaderDuringReconf.
void runTestKillLeaderDuringReconf(CLUSTER cluster) throws Exception {
final AtomicBoolean clientRunning = new AtomicBoolean(true);
Thread clientThread = null;
try {
final RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
PeerChanges c1 = cluster.addNewPeers(1, false);
PeerChanges c2 = cluster.removePeers(1, false, asList(c1.newPeers));
LOG.info("Start setConf: {}", asList(c2.allPeersInNewConf));
LOG.info(cluster.printServers());
final CompletableFuture<Void> setConf = new CompletableFuture<>();
clientThread = new Thread(() -> {
try (final RaftClient client = cluster.createClient(leaderId)) {
for (int i = 0; clientRunning.get() && !setConf.isDone(); i++) {
final RaftClientReply reply = client.admin().setConfiguration(c2.allPeersInNewConf);
if (reply.isSuccess()) {
setConf.complete(null);
}
LOG.info("setConf attempt #{} failed, {}", i, cluster.printServers());
}
} catch (Exception e) {
LOG.error("Failed to setConf", e);
setConf.completeExceptionally(e);
}
});
clientThread.start();
TimeUnit.SECONDS.sleep(1);
// the leader cannot generate the (old, new) conf, and it will keep
// bootstrapping the 2 new peers since they have not started yet
Assert.assertFalse(((RaftConfigurationImpl) cluster.getLeader().getRaftConf()).isTransitional());
// only (0) the first conf entry, (1) the 1st setConf entry and (2) a metadata entry
{
final RaftLog leaderLog = cluster.getLeader().getRaftLog();
for (LogEntryProto e : RaftTestUtil.getLogEntryProtos(leaderLog)) {
LOG.info("{}", LogProtoUtils.toLogEntryString(e));
}
final long commitIndex = leaderLog.getLastCommittedIndex();
Assert.assertTrue("commitIndex = " + commitIndex + " > 2", commitIndex <= 2);
}
final RaftPeerId killed = RaftTestUtil.waitAndKillLeader(cluster);
Assert.assertEquals(leaderId, killed);
final RaftPeerId newLeaderId = RaftTestUtil.waitForLeader(cluster).getId();
LOG.info("newLeaderId: {}", newLeaderId);
LOG.info("start new peers: {}", Arrays.asList(c1.newPeers));
for (RaftPeer np : c1.newPeers) {
cluster.restartServer(np.getId(), false);
}
try {
setConf.get(10, TimeUnit.SECONDS);
} catch (TimeoutException ignored) {
}
// the client fails with the first leader, and then retry the same setConfiguration request
waitAndCheckNewConf(cluster, c2.allPeersInNewConf, 2, Collections.singletonList(leaderId));
setConf.get(1, TimeUnit.SECONDS);
} finally {
if (clientThread != null) {
clientRunning.set(false);
clientThread.interrupt();
}
}
}
use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class RaftReconfigurationBaseTest method runTestRevertConfigurationChange.
void runTestRevertConfigurationChange(CLUSTER cluster) throws Exception {
RaftLogBase log2 = null;
try {
RaftTestUtil.waitForLeader(cluster);
final RaftServer.Division leader = cluster.getLeader();
final RaftPeerId leaderId = leader.getId();
final RaftLog log = leader.getRaftLog();
log2 = (RaftLogBase) log;
Thread.sleep(1000);
// we block the incoming msg for the leader and block its requests to
// followers, so that we force the leader change and the old leader will
// not know
LOG.info("start blocking the leader");
BlockRequestHandlingInjection.getInstance().blockReplier(leaderId.toString());
cluster.setBlockRequestsFrom(leaderId.toString(), true);
PeerChanges change = cluster.removePeers(1, false, new ArrayList<>());
AtomicBoolean gotNotLeader = new AtomicBoolean(false);
final Thread clientThread = new Thread(() -> {
try (final RaftClient client = cluster.createClient(leaderId)) {
LOG.info("client starts to change conf");
final RaftClientRpc sender = client.getClientRpc();
RaftClientReply reply = sender.sendRequest(cluster.newSetConfigurationRequest(client.getId(), leaderId, change.allPeersInNewConf));
if (reply.getNotLeaderException() != null) {
gotNotLeader.set(true);
}
} catch (IOException e) {
LOG.warn("Got unexpected exception when client1 changes conf", e);
}
});
clientThread.start();
// find ConfigurationEntry
final TimeDuration sleepTime = TimeDuration.valueOf(500, TimeUnit.MILLISECONDS);
final long confIndex = JavaUtils.attemptRepeatedly(() -> {
final long last = log.getLastEntryTermIndex().getIndex();
for (long i = last; i >= 1; i--) {
if (log.get(i).hasConfigurationEntry()) {
return i;
}
}
throw new Exception("ConfigurationEntry not found: last=" + last);
}, 10, sleepTime, "confIndex", LOG);
// wait till the old leader persist the new conf
JavaUtils.attemptRepeatedly(() -> {
Assert.assertTrue(log.getFlushIndex() >= confIndex);
return null;
}, 10, sleepTime, "FLUSH", LOG);
final long committed = log.getLastCommittedIndex();
Assert.assertTrue(committed < confIndex);
// unblock the old leader
BlockRequestHandlingInjection.getInstance().unblockReplier(leaderId.toString());
cluster.setBlockRequestsFrom(leaderId.toString(), false);
// the client should get NotLeaderException
clientThread.join(5000);
Assert.assertTrue(gotNotLeader.get());
// the old leader should have truncated the setConf from the log
JavaUtils.attemptRepeatedly(() -> {
Assert.assertTrue(log.getLastCommittedIndex() >= confIndex);
return null;
}, 10, ONE_SECOND, "COMMIT", LOG);
Assert.assertTrue(log.get(confIndex).hasConfigurationEntry());
log2 = null;
} finally {
RaftStorageTestUtils.printLog(log2, s -> LOG.info(s));
}
}
use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.
the class LogAppenderTests method runTest.
void runTest(CLUSTER cluster) throws Exception {
final int numMsgs = 10;
final int numClients = 5;
final RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
List<RaftClient> clients = new ArrayList<>();
try {
List<Sender> senders = new ArrayList<>();
// start several clients and write concurrently
final CountDownLatch latch = new CountDownLatch(1);
for (int i = 0; i < numClients; i++) {
RaftClient client = cluster.createClient(leaderId);
clients.add(client);
senders.add(new Sender(client, numMsgs, latch));
}
senders.forEach(Thread::start);
latch.countDown();
for (Sender s : senders) {
s.join();
final Exception e = s.exception.get();
if (e != null) {
throw e;
}
Assert.assertTrue(s.succeed.get());
}
} finally {
for (int i = 0; i < clients.size(); i++) {
try {
clients.get(i).close();
} catch (Exception ignored) {
LOG.warn("{} is ignored", JavaUtils.getClassSimpleName(ignored.getClass()), ignored);
}
}
}
final RaftServer.Division leader = cluster.getLeader();
final RaftLog leaderLog = cluster.getLeader().getRaftLog();
final EnumMap<LogEntryBodyCase, AtomicLong> counts = RaftTestUtil.countEntries(leaderLog);
LOG.info("counts = " + counts);
Assert.assertEquals(6 * numMsgs * numClients, counts.get(LogEntryBodyCase.STATEMACHINELOGENTRY).get());
final LogEntryProto last = RaftTestUtil.getLastEntry(LogEntryBodyCase.STATEMACHINELOGENTRY, leaderLog);
LOG.info("last = {}", LogProtoUtils.toLogEntryString(last));
Assert.assertNotNull(last);
Assert.assertTrue(last.getIndex() <= leader.getInfo().getLastAppliedIndex());
}
Aggregations