use of org.apache.ratis.proto.RaftProtos.LogEntryProto in project incubator-ratis by apache.
the class DataStreamTestUtils method assertLogEntry.
static void assertLogEntry(RaftServer.Division division, SingleDataStream stream) throws Exception {
final RaftClientRequest request = stream.getWriteRequest();
final LogEntryProto entryFromStream = stream.getLogEntry();
assertLogEntry(entryFromStream, request);
final LogEntryProto entryFromLog = searchLogEntry(ClientInvocationId.valueOf(request), division.getRaftLog());
Assert.assertEquals(entryFromStream, entryFromLog);
}
use of org.apache.ratis.proto.RaftProtos.LogEntryProto 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.proto.RaftProtos.LogEntryProto in project incubator-ratis by apache.
the class SimpleStateMachine4Testing method takeSnapshot.
@Override
public long takeSnapshot() {
final TermIndex termIndex = getLastAppliedTermIndex();
if (termIndex.getTerm() <= 0 || termIndex.getIndex() <= 0) {
return RaftLog.INVALID_LOG_INDEX;
}
final long endIndex = termIndex.getIndex();
// TODO: snapshot should be written to a tmp file, then renamed
File snapshotFile = storage.getSnapshotFile(termIndex.getTerm(), termIndex.getIndex());
LOG.debug("Taking a snapshot with t:{}, i:{}, file:{}", termIndex.getTerm(), termIndex.getIndex(), snapshotFile);
try (SegmentedRaftLogOutputStream out = new SegmentedRaftLogOutputStream(snapshotFile, false, segmentMaxSize, preallocatedSize, ByteBuffer.allocateDirect(bufferSize))) {
for (final LogEntryProto entry : indexMap.values()) {
if (entry.getIndex() > endIndex) {
break;
} else {
out.write(entry);
}
}
out.flush();
} catch (IOException e) {
LOG.warn("Failed to take snapshot", e);
}
try {
final MD5Hash digest = MD5FileUtil.computeMd5ForFile(snapshotFile);
MD5FileUtil.saveMD5File(snapshotFile, digest);
} catch (IOException e) {
LOG.warn("Hit IOException when computing MD5 for snapshot file " + snapshotFile, e);
}
try {
this.storage.loadLatestSnapshot();
} catch (IOException e) {
LOG.warn("Hit IOException when loading latest snapshot for snapshot file " + snapshotFile, e);
}
// TODO: purge log segments
return endIndex;
}
use of org.apache.ratis.proto.RaftProtos.LogEntryProto in project incubator-ratis by apache.
the class SimpleStateMachine4Testing method applyTransaction.
@Override
public CompletableFuture<Message> applyTransaction(TransactionContext trx) {
LogEntryProto entry = Objects.requireNonNull(trx.getLogEntry());
put(entry);
updateLastAppliedTermIndex(entry.getTerm(), entry.getIndex());
final SimpleMessage m = new SimpleMessage(entry.getIndex() + " OK");
return collecting.collect(Collecting.Type.APPLY_TRANSACTION, m);
}
use of org.apache.ratis.proto.RaftProtos.LogEntryProto in project incubator-ratis by apache.
the class SimpleStateMachine4Testing method put.
private void put(LogEntryProto entry) {
final LogEntryProto previous = indexMap.put(entry.getIndex(), entry);
Preconditions.assertNull(previous, "previous");
final String s = entry.getStateMachineLogEntry().getLogData().toStringUtf8();
dataMap.put(s, entry);
LOG.info("{}: put {}, {} -> {}", getId(), entry.getIndex(), s.length() <= 10 ? s : s.substring(0, 10) + "...", LogProtoUtils.toLogEntryString(entry));
}
Aggregations