ArrJanitor::Store
SQLite-backed persistence for ArrJanitor.
Tracks two things:
processed_downloads— an audit log of every download ArrJanitor has acted on (for retention/reporting), swept on a TTL.download_states— per-download stalled bookkeeping (groundwork for the stalled-download handling in #9): when a download was first seen stalled.
A single Store (and its underlying DB::Database connection pool) is
meant to be shared across all backend fibers. Under -Dpreview_mt several
fibers may write concurrently; the database is opened in WAL mode with a
busy_timeout so concurrent writers block-and-retry instead of failing
with SQLITE_BUSY. Do not open a Store per call — reuse the shared one.
Constants
How long a writer waits for a competing writer's lock before giving up.
Constructors
Opens (creating if necessary) the SQLite database at path, enables WAL
mode + a busy timeout, runs the schema migrations, and returns a ready
Store. The path is a plain filesystem path (not a sqlite3:// URI).
The pragmas are passed as URI query parameters so crystal-sqlite3 applies
them to every connection the pool opens (the driver runs the URI
pragmas in each new connection's initialize). Setting busy_timeout
via a post-open @db.exec would only configure the single pooled
connection that happened to run it — other connections (created lazily
under -Dpreview_mt) would default to busy_timeout=0 and raise
SQLITE_BUSY immediately instead of blocking-and-retrying. journal_mode
is a persistent file-level setting, but is set via the URI too for
good measure.
NOTE: path is interpolated into the URI unescaped. Paths are local
filenames so this is fine in practice; a path containing URI-significant
characters (e.g. ? or #) would need escaping.
Instance methods
Clears any stored stalled state for (backend, download_id).
Closes the underlying database (flushing the WAL). Idempotent-safe to call once at shutdown.
The time (backend, download_id) was first seen stalled, or nil when
it has no recorded stalled state.
Marks (backend, download_id) as stalled, recording now as the
first-seen-stalled time the first time it is called. Subsequent calls
leave the original first-seen time untouched (only updated_at moves).
Whether a download identified by (backend, download_id) has already
been recorded in processed_downloads.
Records that ArrJanitor took action on the download identified by
(backend, download_id). matched_extensions is the set of bad
extensions/paths that triggered the action; it is stored comma-joined.
created_at defaults to now; it is a parameter so callers (and tests)
can backdate rows through the public API.
Deletes processed_downloads rows older than older_than (relative to
now) and returns the number of rows removed.