refactor(state): drop the hermes_cli ImportError shim from the tracked repair connect
`hermes_cli` ships with every install that has `hermes_state_repair`, so the "scaffold/embed installs without hermes_cli" fallback could never run and only hid a broken import behind an untracked connection. Import directly; docstring keeps the why (locks cancelled by a probe close, howtocorrupt 2.2) and drops the restated mechanism.
This commit is contained in:
@@ -582,26 +582,16 @@ def _connect_repair_durable(db_path: Path, *, timeout: float = 5.0) -> sqlite3.C
|
||||
implicit transaction. Barriers are best-effort: on a malformed schema even ``PRAGMA synchronous=FULL`` raises,
|
||||
so whole-file rewrites call :func:`_reapply_durability_barriers` once the schema parses again.
|
||||
|
||||
Opened through :func:`hermes_cli.sqlite_safe_read.connect_tracked` so the fd is registered for its whole
|
||||
lifetime: the repair paths hold the strongest locks in the process (``_open_exclusive`` keeps
|
||||
``locking_mode=EXCLUSIVE`` across the snapshot → strategies → promotion window, and the write-health probe
|
||||
opens a ``BEGIN IMMEDIATE`` reservation). While untracked, every byte-level probe of a *live* state.db — the
|
||||
zeroed-file detector, header verification, kanban's post-commit page check — was allowed to ``open()``/
|
||||
``close()`` the file, which cancels every POSIX advisory lock this process holds on it
|
||||
(https://sqlite.org/howtocorrupt.html#_posix_advisory_locks_canceled_by_a_separate_thread_doing_close_)
|
||||
and lets an external writer commit into a database the repair still believes it owns (#63386).
|
||||
Tracked (:func:`hermes_cli.sqlite_safe_read.connect_tracked`) because repair connections hold the
|
||||
strongest locks in the process (``locking_mode=EXCLUSIVE``, ``BEGIN IMMEDIATE``); an untracked fd let
|
||||
the byte-level probes ``open()``/``close()`` the live file, which cancels every POSIX advisory lock this
|
||||
process holds on it (sqlite.org/howtocorrupt §2.2) and lets an external writer commit mid-repair (#63386).
|
||||
"""
|
||||
try:
|
||||
from hermes_cli.sqlite_safe_read import connect_tracked
|
||||
except ImportError:
|
||||
# Scaffold/embed installs without hermes_cli: the durable connection stays, only the guard is off.
|
||||
logger.debug("hermes_cli.sqlite_safe_read unavailable; opening %s untracked "
|
||||
"(byte-probe guard inactive in this install)", db_path)
|
||||
conn = sqlite3.connect(str(db_path), timeout=timeout, isolation_level=None)
|
||||
else:
|
||||
# Open through THIS module's sqlite3.connect so tests patching it keep control of the fd.
|
||||
conn = connect_tracked(db_path, tracking_path=db_path, connect_fn=sqlite3.connect,
|
||||
timeout=timeout, isolation_level=None)
|
||||
from hermes_cli.sqlite_safe_read import connect_tracked
|
||||
|
||||
# Through THIS module's sqlite3.connect so tests patching it keep control of the fd.
|
||||
conn = connect_tracked(db_path, tracking_path=db_path, connect_fn=sqlite3.connect,
|
||||
timeout=timeout, isolation_level=None)
|
||||
_reapply_durability_barriers(conn)
|
||||
return conn
|
||||
|
||||
|
||||
Reference in New Issue
Block a user