use of org.apache.ratis.proto.RaftProtos.LogEntryProto in project incubator-ratis by apache.
the class TestLogSegment method testTruncate.
@Test
public void testTruncate() throws Exception {
final long term = 1;
final long start = 1000;
LogSegment segment = LogSegment.newOpenSegment(null, start, null);
for (int i = 0; i < 100; i++) {
LogEntryProto entry = LogProtoUtils.toLogEntryProto(new SimpleOperation("m" + i).getLogEntryContent(), term, i + start);
segment.appendToOpenSegment(entry, LogSegment.Op.WRITE_CACHE_WITHOUT_STATE_MACHINE_CACHE);
}
// truncate an open segment (remove 1080~1099)
long newSize = segment.getLogRecord(start + 80).getOffset();
segment.truncate(start + 80);
Assert.assertEquals(80, segment.numOfEntries());
checkLogSegment(segment, start, start + 79, false, newSize, term);
// truncate a closed segment (remove 1050~1079)
newSize = segment.getLogRecord(start + 50).getOffset();
segment.truncate(start + 50);
Assert.assertEquals(50, segment.numOfEntries());
checkLogSegment(segment, start, start + 49, false, newSize, term);
// truncate all the remaining entries
segment.truncate(start);
Assert.assertEquals(0, segment.numOfEntries());
checkLogSegment(segment, start, start - 1, false, SegmentedRaftLogFormat.getHeaderLength(), term);
}
use of org.apache.ratis.proto.RaftProtos.LogEntryProto in project incubator-ratis by apache.
the class TestSegmentedRaftLog method testServerShutdownOnTimeoutIOException.
@Test(expected = TimeoutIOException.class)
public void testServerShutdownOnTimeoutIOException() throws Throwable {
RaftServerConfigKeys.Log.StateMachineData.setSync(properties, true);
final TimeDuration syncTimeout = TimeDuration.valueOf(100, TimeUnit.MILLISECONDS);
RaftServerConfigKeys.Log.StateMachineData.setSyncTimeout(properties, syncTimeout);
final int numRetries = 2;
RaftServerConfigKeys.Log.StateMachineData.setSyncTimeoutRetry(properties, numRetries);
final LogEntryProto entry = prepareLogEntry(0, 0, null, true);
final StateMachine sm = new BaseStateMachine() {
@Override
public CompletableFuture<Void> write(LogEntryProto entry) {
getLifeCycle().transition(LifeCycle.State.STARTING);
getLifeCycle().transition(LifeCycle.State.RUNNING);
// the future never completes
return new CompletableFuture<>();
}
@Override
public void notifyLogFailed(Throwable cause, LogEntryProto entry) {
LOG.info("Test StateMachine: Ratis log failed notification received as expected.", cause);
LOG.info("Test StateMachine: Transition to PAUSED state.");
Assert.assertNotNull(entry);
getLifeCycle().transition(LifeCycle.State.PAUSING);
getLifeCycle().transition(LifeCycle.State.PAUSED);
}
};
// TimeoutIOException
Throwable ex = null;
try (SegmentedRaftLog raftLog = new SegmentedRaftLog(memberId, null, sm, null, null, storage, () -> -1, properties)) {
raftLog.open(RaftLog.INVALID_LOG_INDEX, null);
// SegmentedRaftLogWorker should catch TimeoutIOException
CompletableFuture<Long> f = raftLog.appendEntry(entry);
// Wait for async writeStateMachineData to finish
try {
f.get();
} catch (ExecutionException e) {
ex = e.getCause();
}
}
Assert.assertNotNull(ex);
Assert.assertSame(LifeCycle.State.PAUSED, sm.getLifeCycleState());
throw ex;
}
use of org.apache.ratis.proto.RaftProtos.LogEntryProto in project incubator-ratis by apache.
the class TestSegmentedRaftLog method testSegmentedRaftLogStateMachineData.
@Test
public void testSegmentedRaftLogStateMachineData() throws Exception {
final SegmentRange range = new SegmentRange(0, 10, 1, true);
final List<LogEntryProto> entries = prepareLogEntries(range, null, true, new ArrayList<>());
final SimpleStateMachine4Testing sm = new SimpleStateMachine4Testing();
try (SegmentedRaftLog raftLog = new SegmentedRaftLog(memberId, null, sm, null, null, storage, () -> -1, properties)) {
raftLog.open(RaftLog.INVALID_LOG_INDEX, null);
int next = 0;
long flush = -1;
assertIndices(raftLog, flush, next);
raftLog.appendEntry(entries.get(next++));
assertIndices(raftLog, flush, next);
raftLog.appendEntry(entries.get(next++));
assertIndices(raftLog, flush, next);
raftLog.appendEntry(entries.get(next++));
assertIndicesMultipleAttempts(raftLog, flush += 3, next);
sm.blockFlushStateMachineData();
raftLog.appendEntry(entries.get(next++));
sm.blockWriteStateMachineData();
final Thread t = startAppendEntryThread(raftLog, entries.get(next++));
TimeUnit.SECONDS.sleep(1);
assertTrue(t.isAlive());
sm.unblockWriteStateMachineData();
assertIndices(raftLog, flush, next);
TimeUnit.SECONDS.sleep(1);
assertIndices(raftLog, flush, next);
sm.unblockFlushStateMachineData();
assertIndicesMultipleAttempts(raftLog, flush + 2, next);
// raftLog.appendEntry(entry).get() won't return
// until sm.unblockFlushStateMachineData() was called.
t.join();
}
}
use of org.apache.ratis.proto.RaftProtos.LogEntryProto in project incubator-ratis by apache.
the class TestSegmentedRaftLog method prepareLog.
private LogEntryProto[] prepareLog(List<SegmentRange> list) throws IOException {
List<LogEntryProto> entryList = new ArrayList<>();
for (SegmentRange range : list) {
final File file = range.getFile(storage);
final int size = (int) (range.end - range.start + 1);
LogEntryProto[] entries = new LogEntryProto[size];
try (SegmentedRaftLogOutputStream out = new SegmentedRaftLogOutputStream(file, false, segmentMaxSize, preallocatedSize, ByteBuffer.allocateDirect(bufferSize))) {
for (int i = 0; i < size; i++) {
SimpleOperation m = new SimpleOperation("m" + (i + range.start));
entries[i] = LogProtoUtils.toLogEntryProto(m.getLogEntryContent(), range.term, i + range.start);
out.write(entries[i]);
}
}
Collections.addAll(entryList, entries);
}
return entryList.toArray(new LogEntryProto[entryList.size()]);
}
use of org.apache.ratis.proto.RaftProtos.LogEntryProto in project incubator-ratis by apache.
the class TestSegmentedRaftLog method testAppendEntriesWithInconsistency.
/**
* Test append with inconsistent entries
*/
@Test
public void testAppendEntriesWithInconsistency() throws Exception {
// prepare the log for truncation
List<SegmentRange> ranges = prepareRanges(0, 5, 200, 0);
List<LogEntryProto> entries = prepareLogEntries(ranges, null);
final RetryCache retryCache = RetryCacheTestUtil.createRetryCache();
try (SegmentedRaftLog raftLog = RetryCacheTestUtil.newSegmentedRaftLog(memberId, retryCache, storage, properties)) {
raftLog.open(RaftLog.INVALID_LOG_INDEX, null);
entries.forEach(entry -> RetryCacheTestUtil.createEntry(retryCache, entry));
// append entries to the raftlog
entries.stream().map(raftLog::appendEntry).forEach(CompletableFuture::join);
}
// append entries whose first 100 entries are the same with existing log,
// and the next 100 are with different term
SegmentRange r1 = new SegmentRange(550, 599, 2, false);
SegmentRange r2 = new SegmentRange(600, 649, 3, false);
SegmentRange r3 = new SegmentRange(650, 749, 10, false);
List<LogEntryProto> newEntries = prepareLogEntries(Arrays.asList(r1, r2, r3), null);
try (SegmentedRaftLog raftLog = RetryCacheTestUtil.newSegmentedRaftLog(memberId, retryCache, storage, properties)) {
raftLog.open(RaftLog.INVALID_LOG_INDEX, null);
LOG.info("newEntries[0] = {}", newEntries.get(0));
final int last = newEntries.size() - 1;
LOG.info("newEntries[{}] = {}", last, newEntries.get(last));
raftLog.append(newEntries.toArray(new LogEntryProto[0])).forEach(CompletableFuture::join);
checkFailedEntries(entries, 650, retryCache);
checkEntries(raftLog, entries, 0, 650);
checkEntries(raftLog, newEntries, 100, 100);
Assert.assertEquals(newEntries.get(newEntries.size() - 1), getLastEntry(raftLog));
Assert.assertEquals(newEntries.get(newEntries.size() - 1).getIndex(), raftLog.getFlushIndex());
}
// load the raftlog again and check
try (SegmentedRaftLog raftLog = RetryCacheTestUtil.newSegmentedRaftLog(memberId, retryCache, storage, properties)) {
raftLog.open(RaftLog.INVALID_LOG_INDEX, null);
checkEntries(raftLog, entries, 0, 650);
checkEntries(raftLog, newEntries, 100, 100);
Assert.assertEquals(newEntries.get(newEntries.size() - 1), getLastEntry(raftLog));
Assert.assertEquals(newEntries.get(newEntries.size() - 1).getIndex(), raftLog.getFlushIndex());
SegmentedRaftLogCache cache = raftLog.getRaftLogCache();
Assert.assertEquals(5, cache.getNumOfSegments());
}
}
Aggregations