Skip to content

Commit ca47633

Browse files
mtopolnikclaude
andcommitted
Add test verifying global auto-flush accumulation across tables
The test covers the scenario where rows are written to multiple tables interleaved (t1, t2, t1, t2, ...) to confirm that auto-flush counts rows globally rather than per-table. A bug was reported where auto-flush seemed to trigger on each table switch instead of accumulating the configured total number of rows. The new test (testAutoFlushAccumulatesRowsAcrossAllTables) uses autoFlushRows=5 with bytes and interval checks disabled, writes 4 interleaved rows across two tables, and asserts: - No flush happens on any of the 4 rows (including table switches) - pendingRowCount reflects the total across all tables - The 5th row triggers the flush by hitting the global row threshold The test confirms the code is correct: QwpWebSocketSender accumulates rows globally via pendingRowCount and shouldAutoFlush() checks that counter against autoFlushRows, with no flush logic in table(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 58df95f commit ca47633

1 file changed

Lines changed: 49 additions & 0 deletions

File tree

core/src/test/java/io/questdb/client/test/cutlass/qwp/client/QwpWebSocketSenderStateTest.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,59 @@
4141
* <li>{@code reset()} discards all pending state, not just the current table buffer.</li>
4242
* <li>Cached timestamp column references are invalidated during flush operations,
4343
* preventing stale writes through freed {@code ColumnBuffer} instances.</li>
44+
* <li>Auto-flush accumulates rows globally across all tables rather than flushing
45+
* per-table on each table switch.</li>
4446
* </ul>
4547
*/
4648
public class QwpWebSocketSenderStateTest extends AbstractTest {
4749

50+
@Test
51+
public void testAutoFlushAccumulatesRowsAcrossAllTables() throws Exception {
52+
assertMemoryLeak(() -> {
53+
// autoFlushRows=5; bytes and interval are disabled to isolate the row-count check.
54+
// The test verifies that switching tables does NOT trigger a flush — flush fires
55+
// only when the TOTAL pending-row count reaches the configured threshold.
56+
QwpWebSocketSender sender = QwpWebSocketSender.createForTesting(
57+
"localhost", 0, 5, 0, 0L, 1
58+
);
59+
try {
60+
setField(sender, "connected", true);
61+
setField(sender, "inFlightWindow", new InFlightWindow(1, InFlightWindow.DEFAULT_TIMEOUT_MS));
62+
63+
// Write 4 rows interleaved between t1 and t2.
64+
// None of these should trigger auto-flush (4 < 5 = autoFlushRows).
65+
sender.table("t1").longColumn("x", 1).at(1, ChronoUnit.MICROS);
66+
sender.table("t2").longColumn("y", 1).at(1, ChronoUnit.MICROS);
67+
sender.table("t1").longColumn("x", 2).at(2, ChronoUnit.MICROS);
68+
sender.table("t2").longColumn("y", 2).at(2, ChronoUnit.MICROS);
69+
70+
// All 4 rows must still be buffered — switching tables must not flush.
71+
QwpTableBuffer t1 = sender.getTableBuffer("t1");
72+
QwpTableBuffer t2 = sender.getTableBuffer("t2");
73+
Assert.assertEquals("t1 should have 2 buffered rows (no premature flush)",
74+
2, t1.getRowCount());
75+
Assert.assertEquals("t2 should have 2 buffered rows (no premature flush)",
76+
2, t2.getRowCount());
77+
Assert.assertEquals("pendingRowCount must reflect all 4 rows across both tables",
78+
4, sender.getPendingRowCount());
79+
80+
// The 5th row hits the global threshold and triggers auto-flush.
81+
// The flush fails because client is null, confirming that flush
82+
// was triggered by the row-count threshold, not by the table switch.
83+
boolean flushTriggered = false;
84+
try {
85+
sender.table("t1").longColumn("x", 3).at(3, ChronoUnit.MICROS);
86+
} catch (Exception expected) {
87+
flushTriggered = true;
88+
}
89+
Assert.assertTrue("auto-flush must be triggered on the 5th row", flushTriggered);
90+
} finally {
91+
setField(sender, "connected", false);
92+
sender.close();
93+
}
94+
});
95+
}
96+
4897
@Test
4998
public void testCachedTimestampColumnInvalidatedDuringFlush() throws Exception {
5099
assertMemoryLeak(() -> {

0 commit comments

Comments
 (0)