v0.50.259 — SessionDB FD-leak hotfix
Tiny focused FD-leak fix. 1 PR plus 1 Opus pre-release advisor follow-up that extends the fix to a sibling leak path on the LRU eviction site.
Fixed
- SessionDB WAL handle leak — close before replacing on cached agent (#1421) —
_run_agent_streamingcreated a newSessionDBinstance per request and replaced the cached agent's_session_dbreference without closing the old one. EachSessionDB.__init__opens a SQLite connection that holds 3 file descriptors once WAL kicks in (state.db,state.db-wal,state.db-shm). After ~73 messages on a long-lived agent (the empirically-confirmed crash count from the bug report), leaked FDs exhausted the 256 default limit causingEMFILEcrashes. Fix wraps the swap with an explicitagent._session_db.close()(idempotent + thread-safe via SessionDB's internal_lock+if self._conn:guard). (#1421, @wali-reheman)
Pre-release hardening (Opus advisor)
- Same FD-leak fix applied to LRU eviction path —
SESSION_AGENT_CACHE.popitem(last=False)was dropping the evicted agent on the floor withevicted_sid, _ = .... The agent's_session_dbwould only release its FDs when GC eventually finalized the agent — which on a long-running server may be never (cyclic refs, extension types holding C handles, etc.). Now captures the evicted entry, calls_evicted_agent._session_db.close()explicitly. Same shape as #1421's fix on the cached-agent reuse path. 5 regression tests intest_v050259_sessiondb_fd_leak.pycover both paths plusSessionDB.close()idempotency.
Tests
3615 passed locally (master 3610, +5 new); 3614 + 1 skipped on CI (the SessionDB.close() idempotency test skips when the hermes-agent repo isn't on the import path). Browser tests + Phase 2 API sanity all green.
Contributors
Full Changelog: v0.50.258...v0.50.259