use of net.openhft.chronicle.queue.ExcerptAppender in project Chronicle-Queue by OpenHFT.
the class DocumentOrderingTest method shouldRecoverFromUnfinishedFirstMessageInPreviousQueue.
@Test
public void shouldRecoverFromUnfinishedFirstMessageInPreviousQueue() throws Exception {
// as below, but don't actually close the initial context
try (final SingleChronicleQueue queue = builder(DirectoryUtils.tempDir("document-ordering"), 1_000L).progressOnContention(progressOnContention).build()) {
final ExcerptAppender excerptAppender = queue.acquireAppender();
final Future<RecordInfo> otherDocumentWriter;
// begin a record in the first cycle file
final DocumentContext documentContext = excerptAppender.writingDocument();
documentContext.wire().getValueOut().int32(counter.getAndIncrement());
// move time to beyond the next cycle
clock.addAndGet(TimeUnit.SECONDS.toMillis(2L));
otherDocumentWriter = attemptToWriteDocument(queue);
assertEquals(1, otherDocumentWriter.get(5L, TimeUnit.SECONDS).counterValue);
final ExcerptTailer tailer = queue.createTailer();
expectValue(1, tailer);
assertThat(tailer.readingDocument().isPresent(), is(false));
}
}
use of net.openhft.chronicle.queue.ExcerptAppender in project Chronicle-Queue by OpenHFT.
the class EofMarkerOnEmptyQueueTest method shouldRecoverFromEmptyQueueOnRoll.
@Test
public void shouldRecoverFromEmptyQueueOnRoll() throws Exception {
final AtomicLong clock = new AtomicLong(System.currentTimeMillis());
try (final SingleChronicleQueue queue = SingleChronicleQueueBuilder.binary(tmpFolder.newFolder()).rollCycle(RollCycles.TEST_SECONDLY).timeProvider(clock::get).timeoutMS(1_000).testBlockSize().build()) {
final ExcerptAppender appender = queue.acquireAppender();
final DocumentContext context = appender.writingDocument();
// start to write a message, but don't close the context - simulates crashed writer
final long expectedEofMarkerPosition = context.wire().bytes().writePosition() - Wires.SPB_HEADER_SIZE;
context.wire().writeEventName("foo").int32(1);
final int startCycle = queue.cycle();
clock.addAndGet(TimeUnit.SECONDS.toMillis(1L));
final int nextCycle = queue.cycle();
// ensure that the cycle file will roll
assertThat(startCycle, is(not(nextCycle)));
Executors.newSingleThreadExecutor().submit(() -> {
try (final DocumentContext nextCtx = queue.acquireAppender().writingDocument()) {
nextCtx.wire().writeEventName("bar").int32(7);
}
}).get(3, TimeUnit.SECONDS);
final WireStore firstCycleStore = queue.storeForCycle(startCycle, 0, false);
final long firstCycleWritePosition = firstCycleStore.writePosition();
// assert that no write was completed
assertThat(firstCycleWritePosition, is(0L));
final ExcerptTailer tailer = queue.createTailer();
int recordCount = 0;
int lastItem = -1;
while (true) {
try (final DocumentContext readCtx = tailer.readingDocument()) {
if (!readCtx.isPresent()) {
break;
}
final StringBuilder name = new StringBuilder();
final ValueIn field = readCtx.wire().readEventName(name);
recordCount++;
lastItem = field.int32();
}
}
assertThat(firstCycleStore.bytes().readVolatileInt(expectedEofMarkerPosition), is(Wires.END_OF_DATA));
assertThat(recordCount, is(1));
assertThat(lastItem, is(7));
}
}
use of net.openhft.chronicle.queue.ExcerptAppender in project Chronicle-Queue by OpenHFT.
the class IndexTest method test.
@Test
public void test() throws IOException {
try (final RollingChronicleQueue queue = SingleChronicleQueueBuilder.binary(getTmpDir()).testBlockSize().wireType(this.wireType).build()) {
final ExcerptAppender appender = queue.acquireAppender();
for (int i = 0; i < 5; i++) {
final int n = i;
appender.writeDocument(w -> w.write(TestKey.test).int32(n));
final int cycle = queue.lastCycle();
long index0 = queue.rollCycle().toIndex(cycle, n);
long indexA = appender.lastIndexAppended();
accessHexEquals(index0, indexA);
}
}
}
use of net.openhft.chronicle.queue.ExcerptAppender in project Chronicle-Queue by OpenHFT.
the class IndexTest method shouldShortCircuitIndexLookupWhenNewIndexIsCloseToPreviousIndex.
@Test
public void shouldShortCircuitIndexLookupWhenNewIndexIsCloseToPreviousIndex() throws Exception {
try (final SingleChronicleQueue queue = SingleChronicleQueueBuilder.binary(getTmpDir()).testBlockSize().wireType(this.wireType).build()) {
final ExcerptAppender appender = queue.acquireAppender();
final int messageCount = INDEXING_LINEAR_SCAN_THRESHOLD + 5;
final long[] indices = new long[messageCount];
for (int i = 0; i < messageCount; i++) {
try (final DocumentContext ctx = appender.writingDocument()) {
ctx.wire().write("event").int32(i);
indices[i] = ctx.index();
}
}
final SingleChronicleQueueExcerpts.StoreTailer tailer = (SingleChronicleQueueExcerpts.StoreTailer) queue.createTailer();
tailer.moveToIndex(indices[0]);
assertThat(tailer.index(), is(indices[0]));
assertThat(tailer.getIndexMoveCount(), is(1));
tailer.moveToIndex(indices[0]);
assertThat(tailer.index(), is(indices[0]));
assertThat(tailer.getIndexMoveCount(), is(1));
tailer.moveToIndex(indices[2]);
assertThat(tailer.index(), is(indices[2]));
assertThat(tailer.getIndexMoveCount(), is(1));
tailer.moveToIndex(indices[INDEXING_LINEAR_SCAN_THRESHOLD + 2]);
assertThat(tailer.index(), is(indices[INDEXING_LINEAR_SCAN_THRESHOLD + 2]));
assertThat(tailer.getIndexMoveCount(), is(2));
// document that moving backwards requires an index scan
tailer.moveToIndex(indices[INDEXING_LINEAR_SCAN_THRESHOLD - 1]);
assertThat(tailer.index(), is(indices[INDEXING_LINEAR_SCAN_THRESHOLD - 1]));
assertThat(tailer.getIndexMoveCount(), is(3));
}
}
use of net.openhft.chronicle.queue.ExcerptAppender in project Chronicle-Queue by OpenHFT.
the class MoveToIndexTest method testRandomMove.
// https://github.com/OpenHFT/Chronicle-Queue/issues/401
@Test
public void testRandomMove() throws Exception {
final Map<Long, String> messageByIndex = new HashMap<>();
try (ChronicleQueue queue = SingleChronicleQueueBuilder.binary(tmpFolder.newFolder()).build()) {
// create a queue and add some excerpts
final ExcerptAppender appender = queue.acquireAppender();
for (int i = 0; i < 10; i++) {
final String message = "msg" + i;
appender.writeDocument(w -> w.write("message").object(message));
final long appendIndex = appender.lastIndexAppended();
messageByIndex.put(appendIndex, message);
}
final Random random = new Random(1510298038000L);
final List<Long> indices = new ArrayList<>(messageByIndex.keySet());
final ExcerptTailer tailer = queue.createTailer();
final AtomicReference<String> capturedMessage = new AtomicReference<>();
for (int i = 0; i < 100; i++) {
final long randomIndex = indices.get(random.nextInt(messageByIndex.keySet().size()));
tailer.moveToIndex(randomIndex);
tailer.readDocument(w -> capturedMessage.set((String) w.read("message").object()));
assertEquals(messageByIndex.get(randomIndex), capturedMessage.get());
tailer.readDocument(w -> w.read("message").object());
}
}
}
Aggregations