Skip to content

Commit 08ebe21

Browse files
committed
test(executor): make the microbatch overlap test wait for overlap instead of sleeping
The concurrent microbatch test relied on a 50 ms sleep for three delta stagings to overlap and saw two under load. After each model's serial first batch, the tracking adapter now holds stagings until three are active, with a 30 s timeout that fails the test with a clear message. Refs: CHI-468
1 parent 34592e9 commit 08ebe21

1 file changed

Lines changed: 23 additions & 4 deletions

File tree

‎tests/integration/src/sqlbuild/executor/build/concurrent/test_microbatch_concurrency.py‎

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from __future__ import annotations
44

55
import threading
6-
import time
76
from pathlib import Path
87
from textwrap import dedent
98
from typing import Any
@@ -22,10 +21,16 @@
2221
run_concurrent_build,
2322
)
2423

24+
_OVERLAP_TIMEOUT_SECONDS: float = 30.0
25+
2526

2627
class _TrackingDuckDbAdapter(DuckDbAdapter):
27-
def __init__(self) -> None:
28+
def __init__(self, *, overlap_target: int) -> None:
2829
self.track_delta_staging = False
30+
self.overlap_target = overlap_target
31+
self.overlap_wait_timed_out = False
32+
self._overlap_reached = threading.Event()
33+
self._serial_first_batch_models: set[str] = set()
2934
self.active_delta_staging = 0
3035
self.max_active_delta_staging = 0
3136
self.active_delta_models: dict[str, int] = {}
@@ -53,7 +58,15 @@ def _execute(self, *, connection: Any, sql: str) -> Any:
5358
self.max_active_delta_models,
5459
len(self.active_delta_models),
5560
)
56-
time.sleep(0.05)
61+
if self.active_delta_staging >= self.overlap_target:
62+
self._overlap_reached.set()
63+
# Each model stages its first batch serially before fanning out.
64+
gated: bool = model_name in self._serial_first_batch_models
65+
self._serial_first_batch_models.add(model_name)
66+
if gated and not self._overlap_reached.wait(timeout=_OVERLAP_TIMEOUT_SECONDS):
67+
with self._tracking_lock:
68+
self.overlap_wait_timed_out = True
69+
self._overlap_reached.set()
5770
try:
5871
return super()._execute(connection=connection, sql=sql)
5972
finally:
@@ -167,7 +180,9 @@ def test_given_three_batch_ceiling_when_incremental_runs_then_batches_overlap(
167180
destination.parent.mkdir(parents=True, exist_ok=True)
168181
destination.write_text(contents, encoding="utf-8")
169182

170-
adapter: _TrackingDuckDbAdapter = _TrackingDuckDbAdapter()
183+
adapter: _TrackingDuckDbAdapter = _TrackingDuckDbAdapter(
184+
overlap_target=test_case.expected_max_active_batches
185+
)
171186
db_path: Path = tmp_path / "test.duckdb"
172187
initial_project_files: dict[str, str] = {
173188
path: contents.replace("batch_concurrency 3", "batch_concurrency 1")
@@ -232,6 +247,10 @@ def test_given_three_batch_ceiling_when_incremental_runs_then_batches_overlap(
232247
adapter=adapter,
233248
)
234249

250+
assert not adapter.overlap_wait_timed_out, (
251+
f"only {adapter.max_active_delta_staging} delta stagings were ever active together; "
252+
f"expected {test_case.expected_max_active_batches} within {_OVERLAP_TIMEOUT_SECONDS}s"
253+
)
235254
assert incremental_result.status == test_case.expected_status
236255
assert adapter.max_active_delta_staging == test_case.expected_max_active_batches
237256
assert adapter.max_active_delta_models == test_case.expected_max_active_models

0 commit comments

Comments
 (0)