fix(state): bound session database file descriptors - #79457
Conversation
|
The shared-reader serialization looks sound, but two failure paths still violate the FD-lifecycle guarantee this PR is meant to establish. 1. Partial reader initialization loses the candidate
The connection has already been physically opened at that point. Falling back to the writer does not retire that candidate. 2. Failed close clears the final owner
Please add deterministic regressions for:
The construction invariant should be: reserve/construct, complete every initialization step, then publish; on any intermediate failure, close the candidate before returning the reservation. If that rollback close itself fails, retain a strong failed-close owner rather than marking the reader absent. The same physical-close rule should apply during Without these paths, normal operation is bounded to one reader, but repeated initialization failures or a close failure can still accumulate unowned descriptors. |
Summary
SessionDBto one synchronized read-only WAL connection instead of retaining one connection per transient reader threadSessionDBinstances on every return pathRoot cause
A long-running macOS gateway reached its 256-descriptor soft limit with 88
state.dband 86state.db-walhandles. The transient gateway reader threads were retained through per-thread SQLite connections, and standalone reaction calls createdSessionDBinstances without deterministic closure. Descriptor exhaustion then surfaced as provider connection failures (OSError: [Errno 24] Too many open filesfollowed byopenai.APIConnectionError).Verification
uv run --extra dev pytest -q tests/test_session_db_read_path_split.py tests/test_message_reactions.py— 19 passed, 4 skippeduv run --extra dev ruff check hermes_state.py tools/react_to_message_tool.py tests/test_session_db_read_path_split.py tests/test_message_reactions.py— passedNotes
The shared read connection has
check_same_thread=Falseand is serialized under an independentRLock, preserving read/write separation while bounding descriptors. Caller-owned reaction databases are never closed by the tool.