mirror of
https://github.com/agent-substrate/substrate.git
synced 2026-10-02 03:24:42 +08:00
Phase 2 of #463, following #735 and #836: `validate-image-cache` drives eviction through `Store.EvictUnused`, deleting its pre-engine prototype. Also carries #836's post-merge review follow-ups. ## Tool - **Prototype evictor deleted** (mtime-sorted tree removal, then dropping every manifest record — no refcounts, no two-phase rename, no restore). The tool now asks the engine to reclaim the shortfall below `--min-free-gb`, so corpus runs exercise production semantics. `--evict-idle` maps to `WithMinAge`. - **`--evict-all`**: one-shot flush, no refs file or auth. Unlike `rm -rf`, running actors' images survive via bundle-spec rooting (`WithActorsDir`). It is not synchronized with a running atelet (the engine's locks are per-process): the pool can't be corrupted, but a layer reused mid-pass can be evicted from under an actor — a not-yet-mounted start fails once and heals; an already-mounted actor can take EIO. Documented, warned at runtime; the intended end state is an atelet-owned flush (RPC or trigger), not a second process in the pool. - **`--evict-idle` floors at 1m when an actors dir exists**: min-age is the only protection that applies across processes, so on a live node it can't be tuned away. Validation hosts (no actors dir) keep full freedom. - Gate-aware errors in both eviction paths (`ErrIncompleteEnumeration` = "did nothing, repair the named path" vs per-item errors = stats still print, exit 1); a 30s cooldown after fruitless passes so workers don't serialize full engine passes when nothing is evictable. ## Carried #836 follow-ups - Negative `--image-cache-gc-period` rejected (was silently disabling the loop); `noteOutcome` extracted with the backoff cadence unit-tested; engine per-pass line demoted to DEBUG (no-target ticks are now silent); single-line sentinel wraps; `filepath.Abs` + table test for the outside-BasePath warning; `runPass`/`Run` covered behind a `gcStore` seam; flag help and README made truthful (`period=0` still runs startup recovery; watermark reads ~5 pts above `df`; the total-size cap still evicts everything evictable under sustained foreign pressure — retention floor named as the extension). ## Testing - Unit: `-race` clean; new tests for backoff cadence, flag validation, path check, `runPass` skip/panic paths, and `Run` (immediate first pass pinned deterministically; ticking covered separately). - Kind: full e2e green; gated-pass arc verified live (one ERROR per tick naming the corrupt record; startup scan gates and recovers; planted orphan reclaimed at restart); `--evict-all` on a live node evicted 4 unrooted images while all rooted images survived. - GKE (6 nodes): zero image-cache log lines fleet-wide at default log level across ticks. - **Corpus sweep** (7.9 GB volume, always-low-water, `--evict-idle=10s` on a host with no actors dir, parallel pulls): 64/64 images validated with two eviction episodes mid-run (62 img / 103 layers / 5.2 GB, then 46 img / 65 layers / 2.7 GB) — continuous eviction under concurrent real pulls, zero races.