Search in sources :

Example 26 with ExcerptTailer

use of net.openhft.chronicle.queue.ExcerptTailer in project Chronicle-Queue by OpenHFT.

the class DocumentOrderingTest method multipleThreadsMustWaitUntilPreviousCycleFileIsCompleted.

@Test
public void multipleThreadsMustWaitUntilPreviousCycleFileIsCompleted() throws Exception {
    Assume.assumeFalse("ordering/atomicity is not guaranteed when using progressOnContention = true," + "as multiple threads can be concurrently executing within a queue's " + "document context when the queue head is contented", progressOnContention);
    final File dir = DirectoryUtils.tempDir("document-ordering");
    // must be different instances of queue to work around synchronization on acquireStore()
    try (final SingleChronicleQueue queue = builder(dir, 5_000L).build();
        final SingleChronicleQueue queue2 = builder(dir, 5_000L).build();
        final SingleChronicleQueue queue3 = builder(dir, 5_000L).build();
        final SingleChronicleQueue queue4 = builder(dir, 5_000L).build()) {
        final ExcerptAppender excerptAppender = queue.acquireAppender();
        final Future<RecordInfo> firstWriter;
        final Future<RecordInfo> secondWriter;
        final Future<RecordInfo> thirdWriter;
        try (final DocumentContext documentContext = excerptAppender.writingDocument()) {
            // move time to beyond the next cycle
            clock.addAndGet(TimeUnit.SECONDS.toMillis(2L));
            // add some jitter to allow threads to race
            firstWriter = attemptToWriteDocument(queue2);
            LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10L));
            secondWriter = attemptToWriteDocument(queue3);
            LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10L));
            thirdWriter = attemptToWriteDocument(queue4);
            // stall this thread, other threads should not be able to advance,
            // since this DocumentContext is still open
            LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2L));
            documentContext.wire().getValueOut().int32(counter.getAndIncrement());
        }
        firstWriter.get(5L, TimeUnit.SECONDS);
        secondWriter.get(5L, TimeUnit.SECONDS);
        thirdWriter.get(5L, TimeUnit.SECONDS);
        final ExcerptTailer tailer = queue.createTailer();
        expectValue(0, tailer);
        expectValue(1, tailer);
        expectValue(2, tailer);
        expectValue(3, tailer);
    }
}
Also used : ExcerptAppender(net.openhft.chronicle.queue.ExcerptAppender) DocumentContext(net.openhft.chronicle.wire.DocumentContext) File(java.io.File) ExcerptTailer(net.openhft.chronicle.queue.ExcerptTailer) Test(org.junit.Test)

Example 27 with ExcerptTailer

use of net.openhft.chronicle.queue.ExcerptTailer in project Chronicle-Queue by OpenHFT.

the class DocumentOrderingTest method queuedWriteInPreviousCycleShouldRespectTotalOrdering.

@Test
public void queuedWriteInPreviousCycleShouldRespectTotalOrdering() throws Exception {
    try (final SingleChronicleQueue queue = builder(DirectoryUtils.tempDir("document-ordering"), 1_000L).build()) {
        Assume.assumeFalse("ordering/atomicity is not guaranteed when using progressOnContention = true," + "as multiple threads can be concurrently executing within a queue's " + "document context when the queue head is contented", progressOnContention);
        final ExcerptAppender excerptAppender = queue.acquireAppender();
        // write initial document
        excerptAppender.writeDocument("foo", ValueOut::text);
        // begin a record in the first cycle file
        final DocumentContext firstOpenDocument = excerptAppender.writingDocument();
        firstOpenDocument.wire().getValueOut().int32(counter.getAndIncrement());
        // start another record in the first cycle file
        // this may be written to either the first or the second cycle file
        final Future<RecordInfo> secondDocumentInFirstCycle = attemptToWriteDocument(queue);
        // move time to beyond the next cycle
        clock.addAndGet(TimeUnit.SECONDS.toMillis(2L));
        final Future<RecordInfo> otherDocumentWriter = attemptToWriteDocument(queue);
        firstOpenDocument.close();
        secondDocumentInFirstCycle.get(5L, TimeUnit.SECONDS);
        final ExcerptTailer tailer = queue.createTailer();
        // discard first record
        tailer.readingDocument().close();
        // assert that records are committed in order
        expectValue(0, tailer);
        expectValue(1, tailer);
        expectValue(2, tailer);
        assertThat(tailer.readingDocument().isPresent(), is(false));
    }
}
Also used : ValueOut(net.openhft.chronicle.wire.ValueOut) ExcerptAppender(net.openhft.chronicle.queue.ExcerptAppender) DocumentContext(net.openhft.chronicle.wire.DocumentContext) ExcerptTailer(net.openhft.chronicle.queue.ExcerptTailer) Test(org.junit.Test)

Example 28 with ExcerptTailer

use of net.openhft.chronicle.queue.ExcerptTailer in project Chronicle-Queue by OpenHFT.

the class DocumentOrderingTest method codeWithinPriorDocumentMustExecuteBeforeSubsequentDocumentWhenQueueIsNotEmpty.

@Test
public void codeWithinPriorDocumentMustExecuteBeforeSubsequentDocumentWhenQueueIsNotEmpty() throws Exception {
    try (final SingleChronicleQueue queue = builder(DirectoryUtils.tempDir("document-ordering"), 3_000L).build()) {
        final ExcerptAppender excerptAppender = queue.acquireAppender();
        excerptAppender.writeDocument("foo", ValueOut::text);
        final Future<RecordInfo> otherDocumentWriter;
        try (final DocumentContext documentContext = excerptAppender.writingDocument()) {
            // move time to beyond the next cycle
            clock.addAndGet(TimeUnit.SECONDS.toMillis(2L));
            otherDocumentWriter = attemptToWriteDocument(queue);
            // stall this thread, other thread should not be able to advance,
            // since this DocumentContext is still open
            LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2L));
            documentContext.wire().getValueOut().int32(counter.getAndIncrement());
        }
        assertEquals(1, otherDocumentWriter.get(5L, TimeUnit.SECONDS).counterValue);
        final ExcerptTailer tailer = queue.createTailer();
        final DocumentContext documentContext = tailer.readingDocument();
        assertTrue(documentContext.isPresent());
        documentContext.close();
        expectValue(0, tailer);
        expectValue(1, tailer);
    }
}
Also used : ValueOut(net.openhft.chronicle.wire.ValueOut) ExcerptAppender(net.openhft.chronicle.queue.ExcerptAppender) DocumentContext(net.openhft.chronicle.wire.DocumentContext) ExcerptTailer(net.openhft.chronicle.queue.ExcerptTailer) Test(org.junit.Test)

Example 29 with ExcerptTailer

use of net.openhft.chronicle.queue.ExcerptTailer in project Chronicle-Queue by OpenHFT.

the class DuplicateMessageReadTest method shouldNotReceiveDuplicateMessages.

@Test
public void shouldNotReceiveDuplicateMessages() throws Exception {
    final File location = DirectoryUtils.tempDir(DuplicateMessageReadTest.class.getSimpleName());
    final SingleChronicleQueue chronicleQueue = SingleChronicleQueueBuilder.binary(location).rollCycle(QUEUE_CYCLE).build();
    final ExcerptAppender appender = chronicleQueue.acquireAppender();
    appender.pretouch();
    final List<Data> expected = new ArrayList<>();
    for (int i = 50; i < 60; i++) {
        expected.add(new Data(i));
    }
    final ExcerptTailer tailer = chronicleQueue.createTailer();
    // move to end of chronicle before writing
    tailer.toEnd();
    for (final Data data : expected) {
        write(appender, data);
    }
    final List<Data> actual = new ArrayList<>();
    Data data;
    while ((data = read(tailer)) != null) {
        actual.add(data);
    }
    assertThat(actual, is(expected));
}
Also used : ExcerptAppender(net.openhft.chronicle.queue.ExcerptAppender) ArrayList(java.util.ArrayList) File(java.io.File) ExcerptTailer(net.openhft.chronicle.queue.ExcerptTailer) Test(org.junit.Test)

Example 30 with ExcerptTailer

use of net.openhft.chronicle.queue.ExcerptTailer in project Chronicle-Queue by OpenHFT.

the class ExcerptsSkippedWhenTailerDirectionNoneTest method shouldNotSkipMessageAtStartOfQueue.

@Test
public void shouldNotSkipMessageAtStartOfQueue() throws Exception {
    final File tmpDir = DirectoryUtils.tempDir(ExcerptsSkippedWhenTailerDirectionNoneTest.class.getSimpleName());
    try (final ChronicleQueue writeQueue = SingleChronicleQueueBuilder.binary(tmpDir).testBlockSize().rollCycle(TEST_DAILY).build()) {
        final ExcerptAppender excerptAppender = writeQueue.acquireAppender();
        try (final DocumentContext ctx = excerptAppender.writingDocument()) {
            ctx.wire().getValueOut().object("first");
        }
        try (final DocumentContext ctx = excerptAppender.writingDocument()) {
            ctx.wire().getValueOut().object("second");
        }
    }
    try (final SingleChronicleQueue readQueue = SingleChronicleQueueBuilder.binary(tmpDir).testBlockSize().rollCycle(TEST_DAILY).build()) {
        final ExcerptTailer tailer = readQueue.createTailer();
        final RollCycle rollCycle = readQueue.rollCycle();
        assertThat(rollCycle.toSequenceNumber(tailer.index()), is(0L));
        try (final DocumentContext ctx = tailer.direction(TailerDirection.NONE).readingDocument()) {
        // access the first document without incrementing sequence number
        }
        assertThat(rollCycle.toSequenceNumber(tailer.index()), is(0L));
        String value;
        try (DocumentContext dc = tailer.direction(TailerDirection.FORWARD).readingDocument()) {
            ValueIn valueIn = dc.wire().getValueIn();
            value = (String) valueIn.object();
        }
        assertThat(rollCycle.toSequenceNumber(tailer.index()), is(1L));
        assertThat(value, is("first"));
        try (DocumentContext dc = tailer.direction(TailerDirection.NONE).readingDocument()) {
            ValueIn valueIn = dc.wire().getValueIn();
            value = (String) valueIn.object();
        }
        assertThat(rollCycle.toSequenceNumber(tailer.index()), is(1L));
        assertThat(value, is("second"));
        try (DocumentContext dc = tailer.direction(TailerDirection.NONE).readingDocument()) {
            ValueIn valueIn = dc.wire().getValueIn();
            value = (String) valueIn.object();
        }
        assertThat(rollCycle.toSequenceNumber(tailer.index()), is(1L));
        assertThat(value, is("second"));
    }
}
Also used : ValueIn(net.openhft.chronicle.wire.ValueIn) ChronicleQueue(net.openhft.chronicle.queue.ChronicleQueue) ExcerptAppender(net.openhft.chronicle.queue.ExcerptAppender) RollCycle(net.openhft.chronicle.queue.RollCycle) DocumentContext(net.openhft.chronicle.wire.DocumentContext) File(java.io.File) ExcerptTailer(net.openhft.chronicle.queue.ExcerptTailer) Test(org.junit.Test)

Aggregations

ExcerptTailer (net.openhft.chronicle.queue.ExcerptTailer)45 Test (org.junit.Test)39 ExcerptAppender (net.openhft.chronicle.queue.ExcerptAppender)34 File (java.io.File)24 DocumentContext (net.openhft.chronicle.wire.DocumentContext)22 ChronicleQueue (net.openhft.chronicle.queue.ChronicleQueue)15 MappedFile (net.openhft.chronicle.bytes.MappedFile)11 ArrayList (java.util.ArrayList)5 MethodReader (net.openhft.chronicle.bytes.MethodReader)5 RollingChronicleQueue (net.openhft.chronicle.queue.impl.RollingChronicleQueue)5 IOException (java.io.IOException)4 SetTimeProvider (net.openhft.chronicle.core.time.SetTimeProvider)4 Arrays (java.util.Arrays)3 Collection (java.util.Collection)3 Bytes (net.openhft.chronicle.bytes.Bytes)3 ChronicleQueueTestBase (net.openhft.chronicle.queue.ChronicleQueueTestBase)3 SingleChronicleQueue (net.openhft.chronicle.queue.impl.single.SingleChronicleQueue)3 Wire (net.openhft.chronicle.wire.Wire)3 ByteBuffer (java.nio.ByteBuffer)2 Future (java.util.concurrent.Future)2