Skip to main content

Module maintenance

Module maintenance 

Source
Expand description

The GC maintenance chain’s consumer side (wave 7 — substrate.md §GC; ADR-019 §6; POC-R’s validated cross-process run, POC-R’s maintenance.rs): the schedule registration + the runner, the maintenance worker’s claim loop, the leader TTL lock, and the sweep dispatch — the chain that turns crate::reactor::MAINTENANCE_QUEUE’s payload vocabulary (MaintenanceJob) into GC.

MaintenanceChain::register_sweep_schedule (the `@every` schedule)
  → the alkstore leader-elected scheduler (run_schedules — one
    leader per fleet, the reserved `__alkstore_scheduler` lock)
  → firing lands in the maintenance queue (the `Sweep` payload)
  → worker claim (the queue's stamped visibility window is the
    discipline: the worker acks inside it — a Sweep dispatch longer
    than its stamped window simply lapses, and the at-least-once
    redelivery is held off by these same locks: the redelivered
    sweep is either a locked-out skip or an alkblobs `SweeperLock`
    abort, never a concurrent double reclaim)
  → named-TTL leader lock ([`MAINTENANCE_LOCK`], cross-process GC
       exclusion; a locked-out sweep is a skip + short retry, a
       value not an error)
  → alkblobs Store::sweep() -> Result<SweepReport, Error>
       (the report is the GC outcome carrier — stages, deletes,
       aborts; Err is substrate-level failure: a data verdict + a
       queue retry, the no-log-dep posture — the outcome is
       observable through the [`WorkerEvent`] seam and get_job)

Wave 6 landed the enqueue producer side only (the recorded interpretation, gate-confirmed); this module is the consumer side — and, the wave-6 gate’s N-b rider, the runner supervision the chain owns:

  • the wake runner (Reactor::run_wake_runner) returns Ok(()) on both recv_timeout Err arms (the alkstore contract’s Closed source-death and Database storage-failure arms collapsed by design), so until supervised a runner stop means wake-driven refresh stops silently — MaintenanceChain’s supervision restarts it on both stop shapes (recovery is a fresh listen, Reactor::run_wake_runner’s posture; the stale window between stop and restart is exactly what the reconcile tick exists to bound).
  • the reconcile tick’s driving mechanism (the wave-6 recorded interpretation’s pinned answer): the chain itself ticks it — MaintenanceOpts::reconcile_tick, one Reactor::reconcile pass per tick alongside the worker loop. (Of the three candidates — a schedule firing, a worker-loop tick, a dedicated job — the chain tick is the shape the supervision already owns: schedule firings land GC jobs into the queue, and a reconcile job variant would be a second vocabulary member for what the runner owns anyway.)
  • the scheduler runner supervision: run_schedules respawns on Err(LeadershipLost) (the alkstore recipe) and propagates any other stop — a substrate-level failure of the scheduler leg is the chain’s failure (the closed-store posture: respawning against a dead store is misdirected).

§The pack-housekeeping consumer (pinned in-task)

The PackHousekeeping job’s consumer action is the through-store pack cache’s release path (PackCache::release_all) — the released packs’ pins drop, and the next sweep reclaims their pack blobs (substrate.md §object storage). The whole cache releases: the request-digest cache is process-local, per-repo scoping is a non-goal, and the enqueue leg’s repo id is observation data only. An assembly without a through-store PackGen carries no cache (MaintenanceChain::new’s packs: None) — such a job acks with nothing to release, the composition-honest shape.

§The sweep verdicts (data, never errors)

  • a completed report (SweepReport.aborted included — an aborted sweep is still a ran sweep, its result carried) — acked;
  • a locked-out sweep (MAINTENANCE_LOCK held elsewhere — cross-process GC exclusion is the point) — a skip + short retry, a value: the job goes back to pending with LOCKED_OUT_RETRY_SECS;
  • a substrate-level sweep failure (alkblobs Err) — a data verdict + a queue retry (the at-least-once curve runs it again; max attempts dead-letters it, observable via get_job).

A poison payload (a foreign producer on the queue, codec drift) dead-letters immediately (fail) — the stream consumer’s poison posture, queue-shaped: never a wedge, never a retry loop.

Structs§

MaintenanceChain
The maintenance chain’s consumer side — the schedule registration + the runner, the worker’s claim loop, the leader TTL lock, the sweep dispatch, and the supervised halves the wave-6 gate booked the chain to own (the wake runner’s restart on both stop shapes; the reconcile tick’s driving).
MaintenanceOpts
The chain’s tuning datums (assembly-level knobs, not structure — the schedule spec is the sweep cadence; the tick is the postgres staleness bound; the rest is the loop granularity).

Enums§

SweepVerdict
A sweep job’s outcome, as data (substrate.md §GC — the chain never turns a sweep outcome into an error).
WorkerEvent
What the maintenance worker did — the observation seam (the logged-as-data posture: the outcome carriers surface here, no tracing dependency exists anywhere). A consumer of MaintenanceChain::run sees every executed or skipped job.

Constants§

LOCKED_OUT_RETRY_SECS
Seconds a locked-out sweep goes back to pending for (the short retry — a value, not an error; ADR-019 §6; the schedule’s own cadence is the backstop after it).
SWEEP_SCHEDULE
The sweep schedule’s name — registered (upsert by name) firing into MAINTENANCE_QUEUE with the MaintenanceJob::Sweep payload (the POC-R-validated schedule; the chain’s runner supervision owns the run_schedules side).