Search in sources :

Example 31 with DocumentContext

use of net.openhft.chronicle.wire.DocumentContext in project Chronicle-Queue by OpenHFT.

the class AppenderLockOnlyAppliesToFileTest method concurrentLockItUp.

/*
    Failed tests:
  AppenderLockOnlyAppliesToFileTest.concurrentLockItUp:59 Writer thread completed before timeout

     */
@Ignore("fails too often")
@Test
public void concurrentLockItUp() throws InterruptedException {
    final AtomicReference<String> writerQueueFile = new AtomicReference<>();
    final File path = DirectoryUtils.tempDir(this.getClass().getSimpleName());
    final SingleChronicleQueueBuilder builder = ChronicleQueueBuilder.single(path).sourceId(1).rollCycle(ROLL_CYCLE).timeoutMS(TIMEOUT_MS);
    final String initialFile;
    final DocumentContext initialContext = builder.build().acquireAppender().writingDocument();
    initialContext.wire().writeText("abcd");
    initialFile = getFilename(initialContext);
    // don't close context
    final long afterInitialWrite = System.currentTimeMillis();
    final CountDownLatch writerStarted = new CountDownLatch(1);
    final CountDownLatch writerFinished = new CountDownLatch(1);
    Thread writerThread = new Thread(() -> {
        ExcerptAppender appender = builder.build().acquireAppender();
        writerStarted.countDown();
        // wait for less than timeout and more than roll
        Jvm.pause(WAIT_FOR_ROLL_MS);
        try (@NotNull DocumentContext context = appender.writingDocument()) {
            // should not have been held up by locking
            writerQueueFile.set(getFilename(context));
            Wire wire = context.wire();
            wire.writeText("hello");
            writerFinished.countDown();
        }
    });
    writerThread.start();
    assertTrue("Writer thread not started", writerStarted.await(1, TimeUnit.SECONDS));
    assertTrue("Writer thread completed before timeout", writerFinished.await(WAIT_FOR_ROLL_MS + 50, TimeUnit.MILLISECONDS));
    assertFalse("Threads wrote to different queue cycles, so no locking occurred", initialFile.equals(writerQueueFile.get()));
    assertTrue("We are within timeout", System.currentTimeMillis() < afterInitialWrite + TIMEOUT_MS);
    ExcerptTailer tailer = builder.build().createTailer();
    // this call to readingDocument waits for timeout and logs out ".... resetting header after timeout ...."
    try (DocumentContext rd = tailer.readingDocument()) {
        assertFalse("We are outside timeout", System.currentTimeMillis() < afterInitialWrite + TIMEOUT_MS);
        assertTrue("Something was written", rd.isPresent());
        String value = rd.wire().readText();
        assertEquals("the first (locked) write is lost", "hello", value);
    }
    try (DocumentContext rd = tailer.readingDocument()) {
        assertFalse("Should be only one message in the queue", rd.isPresent());
    }
    try {
        initialContext.close();
        fail("close should have thrown");
    } catch (IllegalStateException e) {
    // expected for close to throw
    }
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) Wire(net.openhft.chronicle.wire.Wire) NotNull(org.jetbrains.annotations.NotNull) DocumentContext(net.openhft.chronicle.wire.DocumentContext) File(java.io.File) MappedFile(net.openhft.chronicle.bytes.MappedFile) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 32 with DocumentContext

use of net.openhft.chronicle.wire.DocumentContext in project Chronicle-Queue by OpenHFT.

the class DetectNotReadyEntriesTest method testDeadEntries.

@Test
public void testDeadEntries() throws FileNotFoundException {
    // TODO FIX.
    if (OS.isWindows())
        return;
    File dir = new File(OS.TARGET, getClass().getSimpleName() + "-" + System.nanoTime());
    dir.mkdir();
    MappedBytes bytes = MappedBytes.mappedBytes(new File(dir, "19700101" + SingleChronicleQueue.SUFFIX), 64 << 10);
    Wire wire = new BinaryWire(bytes);
    try (DocumentContext dc = wire.writingDocument(true)) {
        dc.wire().writeEventName(() -> "header").typePrefix(SingleChronicleQueueStore.class).marshallable(w -> {
            w.write(() -> "wireType").object(WireType.BINARY);
            w.write(() -> "writePosition").int64forBinding(288 + 4 + 17);
            w.write(() -> "roll").typedMarshallable(new SCQRoll(RollCycles.DAILY, 0));
            w.write(() -> "indexing").typedMarshallable(new SCQIndexing(WireType.BINARY, 32 << 10, 32));
            w.write(() -> "lastAcknowledgedIndexReplicated").int64forBinding(0);
        });
    }
    long pos = wire.bytes().writePosition();
    try (DocumentContext dc = wire.writingDocument(false)) {
        dc.wire().write("test").text("Hello World");
    }
    assertEquals(17, wire.bytes().readInt(pos));
    // make it incomplete, note that the length is removed,
    // since writing a length into an incomplete excerpt is not allowed
    wire.bytes().writeInt(pos, Wires.NOT_COMPLETE);
    assertEquals("--- !!meta-data #binary\n" + "header: !SCQStore {\n" + "  wireType: !WireType BINARY,\n" + "  writePosition: 309,\n" + "  roll: !SCQSRoll {\n" + "    length: !int 86400000,\n" + "    format: yyyyMMdd,\n" + "    epoch: 0\n" + "  },\n" + "  indexing: !SCQSIndexing {\n" + "    indexCount: !int 32768,\n" + "    indexSpacing: 32,\n" + "    index2Index: 0,\n" + "    lastIndex: 0\n" + "  },\n" + "  lastAcknowledgedIndexReplicated: 0\n" + "}\n" + "# position: 288, header: -1 or 0\n" + "--- !!not-ready-data! #binary\n" + "...\n" + "# 17 bytes remaining\n", Wires.fromSizePrefixedBlobs(bytes.readPosition(0)));
    bytes.release();
    try (SingleChronicleQueue queue = SingleChronicleQueueBuilder.binary(dir).testBlockSize().build()) {
        queue.acquireAppender().writeText("Bye for now");
    }
    try {
        IOTools.shallowDeleteDirWithFiles(dir.getAbsolutePath());
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Also used : BinaryWire(net.openhft.chronicle.wire.BinaryWire) Wire(net.openhft.chronicle.wire.Wire) DocumentContext(net.openhft.chronicle.wire.DocumentContext) File(java.io.File) MappedBytes(net.openhft.chronicle.bytes.MappedBytes) FileNotFoundException(java.io.FileNotFoundException) BinaryWire(net.openhft.chronicle.wire.BinaryWire) Test(org.junit.Test)

Example 33 with DocumentContext

use of net.openhft.chronicle.wire.DocumentContext 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 34 with DocumentContext

use of net.openhft.chronicle.wire.DocumentContext 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 35 with DocumentContext

use of net.openhft.chronicle.wire.DocumentContext in project Chronicle-Queue by OpenHFT.

the class DocumentOrderingTest method expectValue.

private static void expectValue(final int expectedValue, final ExcerptTailer tailer) {
    try (final DocumentContext documentContext = tailer.readingDocument()) {
        assertTrue(documentContext.isPresent());
        assertEquals(expectedValue, documentContext.wire().getValueIn().int32());
    }
}
Also used : DocumentContext(net.openhft.chronicle.wire.DocumentContext)

Aggregations

DocumentContext (net.openhft.chronicle.wire.DocumentContext)54 Test (org.junit.Test)41 ExcerptAppender (net.openhft.chronicle.queue.ExcerptAppender)28 File (java.io.File)22 ExcerptTailer (net.openhft.chronicle.queue.ExcerptTailer)22 MappedFile (net.openhft.chronicle.bytes.MappedFile)12 ChronicleQueue (net.openhft.chronicle.queue.ChronicleQueue)9 SingleChronicleQueue (net.openhft.chronicle.queue.impl.single.SingleChronicleQueue)8 Wire (net.openhft.chronicle.wire.Wire)8 NotNull (org.jetbrains.annotations.NotNull)6 Ignore (org.junit.Ignore)6 Future (java.util.concurrent.Future)4 AtomicLong (java.util.concurrent.atomic.AtomicLong)4 Bytes (net.openhft.chronicle.bytes.Bytes)4 SetTimeProvider (net.openhft.chronicle.core.time.SetTimeProvider)4 ValueOut (net.openhft.chronicle.wire.ValueOut)4 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 ExecutorService (java.util.concurrent.ExecutorService)3 RollingChronicleQueue (net.openhft.chronicle.queue.impl.RollingChronicleQueue)3