Files
local-deep-research/tests/database/test_pool_config.py
LearningCircuit 94d4a580b5 fix: minimal QueuePool with periodic dispose to prevent FD exhaustion (alternative) (#3340)
* fix: minimal QueuePool (pool_size=1) with periodic dispose for FD safety

Alternative to NullPool that keeps connection reuse for performance
while preventing WAL handle accumulation:

- pool_size: 10→1, max_overflow: 30→2 (3–9 FDs/user vs 30–120)
- pool_recycle: 14400s→3600s (shorter recycle window)
- auth_db: pool_size 5→1, max_overflow 10→2
- Periodic engine.dispose() every 30 min in cleanup scheduler —
  closes ALL pooled connections to release leaked WAL/SHM handles
- FD monitoring every 5 min to detect regressions

Benchmark: QueuePool(1) = 0.07ms/query vs NullPool = 0.29ms/query
with SQLCipher. On 20-30 queries per page load, that's ~1.5ms vs ~6ms.

See ADR-0004 for full rationale.

* fix: clean up stale research entries before checking active count

When a research thread crashes (e.g. RuntimeError outside app context),
cleanup_research_resources never runs, leaving IN_PROGRESS rows in
UserActiveResearch permanently. This blocks the queue since the active
count never decreases.

Now sweeps dead threads before counting: if a research_id is in the DB
as IN_PROGRESS but its thread is no longer alive, mark it FAILED and
remove from the in-memory tracking dict.

* chore: demote FD monitoring log from INFO to DEBUG
2026-04-01 01:52:43 +02:00

31 lines
898 B
Python

"""
Test that pool configuration constants have expected values.
These tests ensure consistency across database engines.
If values need to change, update pool_config.py and these tests together.
"""
class TestPoolConfigConstants:
"""Verify shared pool configuration constants."""
def test_pool_pre_ping_is_true(self):
from local_deep_research.database.pool_config import POOL_PRE_PING
assert POOL_PRE_PING is True
def test_pool_recycle_seconds_value(self):
from local_deep_research.database.pool_config import (
POOL_RECYCLE_SECONDS,
)
assert POOL_RECYCLE_SECONDS == 3600
def test_pool_recycle_is_positive_integer(self):
from local_deep_research.database.pool_config import (
POOL_RECYCLE_SECONDS,
)
assert isinstance(POOL_RECYCLE_SECONDS, int)
assert POOL_RECYCLE_SECONDS > 0