Skip to content

Commit 7475af6

Browse files
authored
Known limitation that a read only queue assumes the roll cycle won't 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
1 parent 8650709 commit 7475af6

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

README.adoc

+5
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,11 @@ Non-batching streaming components are highly performant, deterministic, and repr
207207
You can reproduce bugs which only show up after a million events played in a particular order, with accelerated realistic timings.
208208
This makes using Stream processing attractive for systems which need a high degree of quality outcomes.
209209

210+
==== Setting the Roll Cycle of a queue
211+
212+
You can have different instances of `SingleChronicleQueue` set with different roll cycles.
213+
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.
214+
210215
== Downloading Chronicle Queue
211216

212217
Releases are available on Maven Central as:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package net.openhft.chronicle.queue.issue;
2+
3+
import net.openhft.chronicle.core.OS;
4+
import net.openhft.chronicle.core.io.IOTools;
5+
import net.openhft.chronicle.queue.ChronicleQueue;
6+
import net.openhft.chronicle.queue.ExcerptAppender;
7+
import net.openhft.chronicle.queue.ExcerptTailer;
8+
import net.openhft.chronicle.queue.RollCycles;
9+
import net.openhft.chronicle.wire.DocumentContext;
10+
import org.junit.Test;
11+
12+
import static org.junit.Assert.assertEquals;
13+
import static org.junit.Assert.assertFalse;
14+
import static org.junit.Assume.assumeFalse;
15+
16+
/**
17+
* Test class to verify the behavior of Chronicle Queue when changing Roll Cycles.
18+
* It checks the compatibility and visibility of data written with one Roll Cycle
19+
* and accessed with another.
20+
*/
21+
public class ChangeRollCycleTest {
22+
23+
@Test
24+
public void changeRollCycleWithReadOnlyTailer() {
25+
testChangeRollCycle(true);
26+
}
27+
28+
@Test
29+
public void changeRollCycleWithReadWriteTailer() {
30+
testChangeRollCycle(false);
31+
}
32+
33+
/**
34+
* Test the behavior of Chronicle Queue when switching between roll cycles.
35+
*
36+
* @param readOnly whether the tailer should be in read-only mode
37+
*/
38+
private void testChangeRollCycle(boolean readOnly) {
39+
// Define the queue path
40+
String queuePath = OS.getTarget() + "/changeRollCycle-" + System.nanoTime();
41+
42+
43+
// Step 1: Open a queue with a FAST_DAILY roll cycle and a tailer
44+
try (ChronicleQueue q1 = ChronicleQueue.singleBuilder(queuePath)
45+
.rollCycle(RollCycles.FAST_DAILY)
46+
.readOnly(readOnly)
47+
.build();
48+
ExcerptTailer tailer = q1.createTailer()) {
49+
50+
// Verify the queue is initially empty
51+
try (DocumentContext dc = tailer.readingDocument()) {
52+
assertFalse("Queue should be empty initially", dc.isPresent());
53+
}
54+
55+
// Step 2: Reopen the queue with a WEEKLY roll cycle and write data
56+
try (ChronicleQueue q2 = ChronicleQueue.singleBuilder(queuePath)
57+
.rollCycle(RollCycles.WEEKLY)
58+
.build();
59+
ExcerptAppender appender2 = q2.createAppender()) {
60+
61+
// Write a messages to the queue
62+
appender2.writeText("Hello");
63+
64+
// Step 3: Reopen the queue with a WEEKLY roll cycle and write data
65+
try (ChronicleQueue q3 = ChronicleQueue.singleBuilder(queuePath)
66+
.rollCycle(RollCycles.FAST_HOURLY)
67+
.build();
68+
ExcerptAppender appender3 = q3.createAppender()) {
69+
assertEquals(q2.rollCycle(), q3.rollCycle());
70+
71+
// Write two messages to the queue
72+
appender3.writeText("World");
73+
74+
if (readOnly)
75+
assertEquals("Roll cycle should match WEEKLY for read-only mode",
76+
RollCycles.WEEKLY, q3.rollCycle());
77+
}
78+
79+
// If the tailer is read-only, the roll cycle cannot not be changed
80+
// The read only case assumes there queue is historical and the roll cycle is fixed
81+
assumeFalse(readOnly);
82+
83+
// Step 4: Verify the data can be read back correctly
84+
assertEquals("First message should match", "Hello", tailer.readText());
85+
86+
if (readOnly)
87+
assertEquals("Roll cycle should match WEEKLY for read-only mode",
88+
RollCycles.WEEKLY,
89+
q1.rollCycle());
90+
91+
assertEquals("Second message should match", "World", tailer.readText());
92+
93+
assertEquals(q2.rollCycle(), q1.rollCycle());
94+
95+
// Verify there is no extra data in the queue
96+
try (DocumentContext dc = tailer.readingDocument()) {
97+
assertFalse("No more data should be present in the queue", dc.isPresent());
98+
}
99+
}
100+
} finally {
101+
// Clean up the queue directory to avoid leaving test artifacts
102+
IOTools.deleteDirWithFiles(queuePath, 2);
103+
}
104+
}
105+
}

0 commit comments

Comments
 (0)