pub fn reap_stale(connection: &mut PgConnection) -> usizeExpand description
Marks any non-terminal job whose progress heartbeat has been silent for longer than
config().jobs.stale_timeout_seconds as interrupted — the runtime complement to
interrupt_orphans (which only runs at startup). It closes the W-4 zombie: a job whose body
hangs while a long-lived frontend keeps running would otherwise sit running forever, leaking
a thread and lying to every pending-check + the report-refresh debounce. A job that keeps
step-ing stays live (fresh updated_at); only a silent one is reaped. Self-correcting: if
a merely-slow job is reaped and later finishes, its finish() overwrites the status, so a
generous timeout costs at most a transient interrupted display. Skew-free (differences against
the DB clock, like db_now). Returns the count reaped; best-effort.
Caveat — Rust cannot force-kill a thread: reaping marks the DB row terminal (so accounting,
pending-checks, and the refresh debounce are correct) but the hung OS thread itself runs until
its body unblocks. The leak is bounded — its pooled connection is returned between steps and
the r2d2 pool caps total connections — but the thread/stack is only reclaimed when the body
returns; truly aborting a hung blocking job would need subprocess isolation (a SIGKILL-able
child), a deliberate architecture trade. See the W-4 ledger entry.