Skip to content

Commit

Permalink
Known limitation that a read only queue assumes the roll cycle won't …
Browse files Browse the repository at this point in the history
…change and is set correctly (#1645)

* Known limitation that a read only queue assumes the roll cycle won't change and is set correctly

* Known limitation that a read only queue assumes the roll cycle won't change and is set correctly
  • Loading branch information
peter-lawrey authored Dec 3, 2024
1 parent 8650709 commit 7475af6
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,11 @@ Non-batching streaming components are highly performant, deterministic, and repr
You can reproduce bugs which only show up after a million events played in a particular order, with accelerated realistic timings.
This makes using Stream processing attractive for systems which need a high degree of quality outcomes.

==== Setting the Roll Cycle of a queue

You can have different instances of `SingleChronicleQueue` set with different roll cycles.
However, if you have instances of `SingleChronicleQueue` with the same path but different roll cycles, first queue to be created determines the roll cycle, even if the first queue only have a tailer. If the first queue is read-only, it will fail to read the queue if the roll cycle is later different.

== Downloading Chronicle Queue

Releases are available on Maven Central as:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package net.openhft.chronicle.queue.issue;

import net.openhft.chronicle.core.OS;
import net.openhft.chronicle.core.io.IOTools;
import net.openhft.chronicle.queue.ChronicleQueue;
import net.openhft.chronicle.queue.ExcerptAppender;
import net.openhft.chronicle.queue.ExcerptTailer;
import net.openhft.chronicle.queue.RollCycles;
import net.openhft.chronicle.wire.DocumentContext;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assume.assumeFalse;

/**
* Test class to verify the behavior of Chronicle Queue when changing Roll Cycles.
* It checks the compatibility and visibility of data written with one Roll Cycle
* and accessed with another.
*/
public class ChangeRollCycleTest {

@Test
public void changeRollCycleWithReadOnlyTailer() {
testChangeRollCycle(true);
}

@Test
public void changeRollCycleWithReadWriteTailer() {
testChangeRollCycle(false);
}

/**
* Test the behavior of Chronicle Queue when switching between roll cycles.
*
* @param readOnly whether the tailer should be in read-only mode
*/
private void testChangeRollCycle(boolean readOnly) {
// Define the queue path
String queuePath = OS.getTarget() + "/changeRollCycle-" + System.nanoTime();


// Step 1: Open a queue with a FAST_DAILY roll cycle and a tailer
try (ChronicleQueue q1 = ChronicleQueue.singleBuilder(queuePath)
.rollCycle(RollCycles.FAST_DAILY)
.readOnly(readOnly)
.build();
ExcerptTailer tailer = q1.createTailer()) {

// Verify the queue is initially empty
try (DocumentContext dc = tailer.readingDocument()) {
assertFalse("Queue should be empty initially", dc.isPresent());
}

// Step 2: Reopen the queue with a WEEKLY roll cycle and write data
try (ChronicleQueue q2 = ChronicleQueue.singleBuilder(queuePath)
.rollCycle(RollCycles.WEEKLY)
.build();
ExcerptAppender appender2 = q2.createAppender()) {

// Write a messages to the queue
appender2.writeText("Hello");

// Step 3: Reopen the queue with a WEEKLY roll cycle and write data
try (ChronicleQueue q3 = ChronicleQueue.singleBuilder(queuePath)
.rollCycle(RollCycles.FAST_HOURLY)
.build();
ExcerptAppender appender3 = q3.createAppender()) {
assertEquals(q2.rollCycle(), q3.rollCycle());

// Write two messages to the queue
appender3.writeText("World");

if (readOnly)
assertEquals("Roll cycle should match WEEKLY for read-only mode",
RollCycles.WEEKLY, q3.rollCycle());
}

// If the tailer is read-only, the roll cycle cannot not be changed
// The read only case assumes there queue is historical and the roll cycle is fixed
assumeFalse(readOnly);

// Step 4: Verify the data can be read back correctly
assertEquals("First message should match", "Hello", tailer.readText());

if (readOnly)
assertEquals("Roll cycle should match WEEKLY for read-only mode",
RollCycles.WEEKLY,
q1.rollCycle());

assertEquals("Second message should match", "World", tailer.readText());

assertEquals(q2.rollCycle(), q1.rollCycle());

// Verify there is no extra data in the queue
try (DocumentContext dc = tailer.readingDocument()) {
assertFalse("No more data should be present in the queue", dc.isPresent());
}
}
} finally {
// Clean up the queue directory to avoid leaving test artifacts
IOTools.deleteDirWithFiles(queuePath, 2);
}
}
}

0 comments on commit 7475af6

Please sign in to comment.