The delete step of the layer GC, factored out of the Gc server so its
safety contracts are testable against a real database without the
cluster-singleton GenServer around them:
- a missing blob still referenced by an image is dangling — reported, never deleted;
- rows younger than
grace_periodare never deleted; - the
DELETEre-checksNOT EXISTS (image_layers), so a reference that appeared after the caller's snapshot is skipped, not violated; - the shared medium is re-probed before any delete, so a mount that vanished mid-page skips the page instead of mass-deleting;
presence/1maps only a true:enoentto:missing; any other I/O error is:unknownand never drives a delete.
Every query runs at low priority: in a transaction with a capped per-statement timeout, so the GC can never pin a backend.
Summary
Functions
Act on one page's missing set: re-check the medium is still mounted, split
dangling (still referenced) from prunable, delete what is out of grace.
Returns {pruned, pruned_bytes, dangling}.
Shared-medium presence probe injected into the pure Sweep core.
Distinguishes a genuine absence (:enoent -> prunable) from an I/O error
(:unknown -> never pruned), so a transient NFS hiccup can never drive a
delete.
Run a DB operation at low priority: in a transaction with a capped per-statement timeout, so it can never pin a backend and yields under contention.
Functions
@spec execute(Hyper.Cfg.Gc.t(), [Hyper.Img.Db.Gc.Sweep.blob()]) :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}
Act on one page's missing set: re-check the medium is still mounted, split
dangling (still referenced) from prunable, delete what is out of grace.
Returns {pruned, pruned_bytes, dangling}.
@spec presence(String.t()) :: Hyper.Img.Db.Gc.Sweep.presence()
Shared-medium presence probe injected into the pure Sweep core.
Distinguishes a genuine absence (:enoent -> prunable) from an I/O error
(:unknown -> never pruned), so a transient NFS hiccup can never drive a
delete.
@spec with_low_priority(Hyper.Cfg.Gc.t(), (-> result)) :: result when result: var
Run a DB operation at low priority: in a transaction with a capped per-statement timeout, so it can never pin a backend and yields under contention.