Skip to content

fix(cron): close SQLite connections in executions ledger to prevent FD exhaustion (#69567) - #70917

Closed
webtecnica wants to merge 2 commits into
NousResearch:mainfrom
webtecnica:fix/cron-sqlite-connection-leak
Closed

fix(cron): close SQLite connections in executions ledger to prevent FD exhaustion (#69567)#70917
webtecnica wants to merge 2 commits into
NousResearch:mainfrom
webtecnica:fix/cron-sqlite-connection-leak

Conversation

@webtecnica

Copy link
Copy Markdown
Contributor

Closes #69567

The cron execution ledger was leaking SQLite connections because sqlite3.Connection as a context manager only commits/rolls back -- it does NOT close the connection. Without explicit conn.close(), every ledger call left an open connection and its WAL/SHM file descriptors.

Created a _transaction() context manager that wraps lock acquisition, connection open, schema initialization, transaction commit/rollback, and deterministic connection close in a finally block. Schema init runs inside the try so PRAGMA/DDL failures after a successful connect still close the connection.

Key design:

  • _connect() now only opens the connection
  • _initialize_schema(conn) handles PRAGMAs, DDL, and WAL setup (preserving apply_wal_with_fallback for NFS/SMB compatibility)
  • _transaction() combines lock + connect + init + commit/rollback + close
  • All 7 call sites migrated

Added regression test test_every_ledger_call_closes_sqlite_connection that runs 10 full lifecycles through every ledger function and asserts /proc/self/fd count for executions.db does not grow.

18 passed

…D exhaustion (NousResearch#69567)

The cron execution ledger was leaking SQLite connections because `sqlite3.Connection` as a context manager only commits/rolls back -- it does NOT close the connection. Without explicit `conn.close()`, every ledger call (create, mark_running, finish, recover, list, latest) left an open connection and its WAL/SHM file descriptors.

Created a `_transaction()` context manager that wraps lock acquisition, connection open, schema initialization, transaction commit/rollback, and deterministic connection close in a `finally` block. Schema init runs inside the `try` too so PRAGMA/DDL failures after a successful connect still close the connection.

Key design:
- `_connect()` now only opens the connection (no schema)
- `_initialize_schema(conn)` handles PRAGMAs, DDL, and WAL setup
- `_transaction()` combines lock + connect + init + commit/rollback + close
- `apply_wal_with_fallback` is preserved (unlike PR NousResearch#69594 which replaced it with raw PRAGMA, losing NFS/SMB fallback)

All 7 call sites migrated from `with _lock, _connect() as conn:` to `with _transaction() as conn:`.

Added regression test `test_every_ledger_call_closes_sqlite_connection` that repeatedly calls all ledger functions and asserts the /proc/self/fd count for executions.db doesn't grow.
@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround comp/cron Cron scheduler and job management duplicate This issue or pull request already exists labels Jul 24, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Duplicate of #69594: both repair the cron executions-ledger connection leak with a deterministic close transaction. #69594 is the earlier open focused canonical.

@teknium1

Copy link
Copy Markdown
Contributor

Closing: duplicate of #69594 (earlier submission) — the cron executions ledger is fixed on main via #70985.

@teknium1 teknium1 closed this Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cron Cron scheduler and job management duplicate This issue or pull request already exists P1 High — major feature broken, no workaround type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: cron execution ledger leaks three SQLite connections per run, exhausting file descriptors

3 participants