mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-10 02:24:35 +08:00
fix(sqlite-store): improve thread tracking in connection cleanup
Add fallback validation to detect dead threads missed by threading.enumerate(), ensuring all stale connections are cleaned. Solution-ID: SOL-1735392000002 Issue-ID: ISS-1766921318981-3 Task-ID: T2
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import threading
|
||||
import time
|
||||
from pathlib import Path
|
||||
@@ -59,3 +60,57 @@ def test_periodic_cleanup(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> No
|
||||
store.close()
|
||||
|
||||
|
||||
def test_cleanup_robustness(
|
||||
monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture, tmp_path: Path
|
||||
) -> None:
|
||||
"""Cleanup should handle dead threads, idle timeouts, and invalid connections."""
|
||||
monkeypatch.setattr(SQLiteStore, "CLEANUP_INTERVAL", 0)
|
||||
caplog.set_level(logging.DEBUG, logger="codexlens.storage.sqlite_store")
|
||||
|
||||
store = SQLiteStore(tmp_path / "cleanup_robustness.db")
|
||||
store.initialize()
|
||||
|
||||
try:
|
||||
# Invalid connection: active thread but pooled connection is already closed.
|
||||
conn = store._get_connection()
|
||||
conn.close()
|
||||
with store._pool_lock:
|
||||
store._pool[threading.get_ident()] = (conn, time.time())
|
||||
store._cleanup_stale_connections()
|
||||
|
||||
assert "invalid_connection" in caplog.text
|
||||
assert threading.get_ident() not in store._pool
|
||||
|
||||
# Ensure next access recreates a working connection after cleanup.
|
||||
fresh_conn = store._get_connection()
|
||||
assert fresh_conn is not conn
|
||||
|
||||
# Idle timeout cleanup should be logged distinctly.
|
||||
with store._pool_lock:
|
||||
store._pool[threading.get_ident()] = (fresh_conn, time.time() - store.IDLE_TIMEOUT - 1)
|
||||
store._cleanup_stale_connections()
|
||||
|
||||
assert "idle_timeout" in caplog.text
|
||||
assert threading.get_ident() not in store._pool
|
||||
|
||||
# Dead thread cleanup should be logged distinctly.
|
||||
created: list[int] = []
|
||||
|
||||
def worker() -> None:
|
||||
store._get_connection()
|
||||
created.append(threading.get_ident())
|
||||
|
||||
t = threading.Thread(target=worker)
|
||||
t.start()
|
||||
t.join()
|
||||
|
||||
dead_tid = created[0]
|
||||
assert dead_tid in store._pool
|
||||
with store._pool_lock:
|
||||
store._cleanup_stale_connections()
|
||||
|
||||
assert "dead_thread" in caplog.text
|
||||
assert dead_tid not in store._pool
|
||||
finally:
|
||||
store.close()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user