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);
}
}
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));
}
}
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);
}
}
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));
}
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"));
}
}
Aggregations