Fix frozen delta watermark and add error stats, lazy source, concurrent disk reads, and per-engine config

This commit is contained in:
Jan Doubravský
2026-06-08 19:35:33 +02:00
parent 209ae667ab
commit 6dc85e4f3c
17 changed files with 668 additions and 71 deletions
+54
View File
@@ -124,6 +124,22 @@ def test_second_query_same_columns_is_cache_hit(engine):
assert len(rows) == 3
def test_cache_hit_does_not_open_source(engine, source_engine, monkeypatch):
"""A pure cache hit must not open a source connection (lazy source)."""
engine.execute("SELECT id, name FROM products") # miss → caches
calls = {"n": 0}
original_connect = source_engine.connect
def counting_connect(*args, **kwargs):
calls["n"] += 1
return original_connect(*args, **kwargs)
monkeypatch.setattr(source_engine, "connect", counting_connect)
engine.execute("SELECT id, name FROM products") # hit → no source access
assert calls["n"] == 0
# ---------------------------------------------------------------------------
# SQL file creation — backup to disk
# ---------------------------------------------------------------------------
@@ -331,3 +347,41 @@ def test_in_memory_override_respects_config(source_engine, cache_path, monkeypat
ce = CachingEngine(source_engine) # no explicit in_memory
assert ce._cache._in_memory is False
ce.close()
# ---------------------------------------------------------------------------
# Per-engine configuration (constructor overrides env defaults)
# ---------------------------------------------------------------------------
def test_constructor_config_overrides(source_engine, tmp_path):
p = tmp_path / "explicit_cache.db"
ce = CachingEngine(
source_engine,
cache_db_path=p,
fetch_batch=3,
dialect="sqlite",
backup_interval=12345,
refresh_interval=42,
in_memory=False,
)
ce.execute("SELECT id, name FROM products")
assert p.exists()
assert ce._cache._fetch_batch == 3
assert ce._cache._dialect == "sqlite"
assert ce._dialect == "sqlite"
assert ce._cache._backup_interval == 12345
assert ce._refresh_interval == 42
ce.close()
def test_two_engines_separate_cache_files(source_engine, tmp_path):
"""Two engines in one process can target different cache files."""
a = CachingEngine(source_engine, cache_db_path=tmp_path / "a.db", in_memory=False)
b = CachingEngine(source_engine, cache_db_path=tmp_path / "b.db", in_memory=False)
a.execute("SELECT id FROM products")
assert (tmp_path / "a.db").exists()
assert a._cache.is_table_cached("products") is True
assert b._cache.is_table_cached("products") is False # independent cache
a.close()
b.close()