use of com.alipay.sofa.jraft.entity.UserLog in project sofa-jraft by sofastack.
the class NodeTest method readCommittedUserLog.
@Test
public void readCommittedUserLog() throws Exception {
// setup cluster
final List<PeerId> peers = TestUtils.generatePeers(3);
final TestCluster cluster = new TestCluster("unitest", this.dataPath, peers, 1000);
for (final PeerId peer : peers) {
assertTrue(cluster.start(peer.getEndpoint()));
}
cluster.waitLeader();
final Node leader = cluster.getLeader();
assertNotNull(leader);
this.sendTestTaskAndWait(leader);
// index == 1 is a CONFIGURATION log, so real_index will be 2 when returned.
UserLog userLog = leader.readCommittedUserLog(1);
assertNotNull(userLog);
assertEquals(2, userLog.getIndex());
assertEquals("hello0", new String(userLog.getData().array()));
// index == 5 is a DATA log(a user log)
userLog = leader.readCommittedUserLog(5);
assertNotNull(userLog);
assertEquals(5, userLog.getIndex());
assertEquals("hello3", new String(userLog.getData().array()));
// index == 15 is greater than last_committed_index
try {
assertNull(leader.readCommittedUserLog(15));
fail();
} catch (final LogIndexOutOfBoundsException e) {
assertEquals(e.getMessage(), "Request index 15 is greater than lastAppliedIndex: 11");
}
// index == 0 invalid request
try {
assertNull(leader.readCommittedUserLog(0));
fail();
} catch (final LogIndexOutOfBoundsException e) {
assertEquals(e.getMessage(), "Request index is invalid: 0");
}
LOG.info("Trigger leader snapshot");
CountDownLatch latch = new CountDownLatch(1);
leader.snapshot(new ExpectClosure(latch));
waitLatch(latch);
// remove and add a peer to add two CONFIGURATION logs
final List<Node> followers = cluster.getFollowers();
assertEquals(2, followers.size());
final Node testFollower = followers.get(0);
latch = new CountDownLatch(1);
leader.removePeer(testFollower.getNodeId().getPeerId(), new ExpectClosure(latch));
waitLatch(latch);
latch = new CountDownLatch(1);
leader.addPeer(testFollower.getNodeId().getPeerId(), new ExpectClosure(latch));
waitLatch(latch);
this.sendTestTaskAndWait(leader, 10, RaftError.SUCCESS);
// trigger leader snapshot for the second time, after this the log of index 1~11 will be deleted.
LOG.info("Trigger leader snapshot");
latch = new CountDownLatch(1);
leader.snapshot(new ExpectClosure(latch));
waitLatch(latch);
Thread.sleep(100);
// index == 5 log has been deleted in log_storage.
try {
leader.readCommittedUserLog(5);
fail();
} catch (final LogNotFoundException e) {
assertEquals("User log is deleted at index: 5", e.getMessage());
}
// index == 12、index == 13、index=14、index=15 are 4 CONFIGURATION logs(joint consensus), so real_index will be 16 when returned.
userLog = leader.readCommittedUserLog(12);
assertNotNull(userLog);
assertEquals(16, userLog.getIndex());
assertEquals("hello10", new String(userLog.getData().array()));
// now index == 17 is a user log
userLog = leader.readCommittedUserLog(17);
assertNotNull(userLog);
assertEquals(17, userLog.getIndex());
assertEquals("hello11", new String(userLog.getData().array()));
cluster.ensureSame();
assertEquals(3, cluster.getFsms().size());
for (final MockStateMachine fsm : cluster.getFsms()) {
assertEquals(20, fsm.getLogs().size());
for (int i = 0; i < 20; i++) {
assertEquals("hello" + i, new String(fsm.getLogs().get(i).array()));
}
}
cluster.stopAll();
}
use of com.alipay.sofa.jraft.entity.UserLog in project sofa-jraft by sofastack.
the class NodeImpl method readCommittedUserLog.
@Override
public UserLog readCommittedUserLog(final long index) {
if (index <= 0) {
throw new LogIndexOutOfBoundsException("Request index is invalid: " + index);
}
final long savedLastAppliedIndex = this.fsmCaller.getLastAppliedIndex();
if (index > savedLastAppliedIndex) {
throw new LogIndexOutOfBoundsException("Request index " + index + " is greater than lastAppliedIndex: " + savedLastAppliedIndex);
}
long curIndex = index;
LogEntry entry = this.logManager.getEntry(curIndex);
if (entry == null) {
throw new LogNotFoundException("User log is deleted at index: " + index);
}
do {
if (entry.getType() == EnumOutter.EntryType.ENTRY_TYPE_DATA) {
return new UserLog(curIndex, entry.getData());
} else {
curIndex++;
}
if (curIndex > savedLastAppliedIndex) {
throw new IllegalStateException("No user log between index:" + index + " and last_applied_index:" + savedLastAppliedIndex);
}
entry = this.logManager.getEntry(curIndex);
} while (entry != null);
throw new LogNotFoundException("User log is deleted at index: " + curIndex);
}
Aggregations