refactor(core): extract shared DebouncedEvictor; adopt in both caches (PSA-43) #12
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/psa-43-debounced-evictor-core"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Extract the single-debounced-evictor mechanism PSA-39 introduced for the OCI blob cache into a shared
dunite_core::services::debounced_evictor::DebouncedEvictor(re-exported asservices::DebouncedEvictor, matching thesingle_flightprecedent), and adopt it in BOTH dunite-ociblob_cacheand dunite-downloaddownload_cache.Why
PSA-39 fixed the OCI cache's per-blob
tokio::spawn(evict_if_over_cap)(N connection-hungry tasks racing a bounded pool -> PoolTimedOut) with a single task poked through a capacity-1 channel. dunite-download still used the old per-store spawn pattern, so the verticals diverged and download carried the same latent bug. Per the architecture rule, cross-vertical sharing goes DOWN into dunite-core.The primitive
DebouncedEvictor::new(label, run)spawns one long-lived task that runs the caller'srunclosure once per coalesced poke, loggingErrat warn under the caller-suppliedlabel.poke()is a capacity-1try_send(bursts coalesce). The task holds only the closure (never a sender), so it exits when the last handle drops. The closure owns the eviction policy; the label owns the wording - no vertical-specific string lives in core.Adoption
blob_cache:run_evictor+evict_txreplaced by aDebouncedEvictorfield built from a closure over the existing freeevict_over_cap;fetch_and_storecallsself.evictor.poke().download_cache: per-storetokio::spawnreplaced the same way; its eviction loop factored into a freeevict_over_cap(negative-total guard +oldest(32)batch preserved exactly) shared byevict_if_over_capand the evictor.evict_if_over_cap(blocking/startup pass). As with PSA-39,BlobCache::new/DownloadCache::newmust now run inside a Tokio runtime.Acceptance criteria
dunite-coreexposes a genericDebouncedEvictorwith unit tests: burst coalesces into far fewer runs than pokes; task exits when all handles drop; an erroring closure is logged and does not kill the task.BlobCacheuses it; its existingburst_..._convergestest passes unchanged.DownloadCacheuses it, with an equivalent burst regression test (8 concurrent stores over cap 250 converge, eviction passes well under 8).cargo test --workspaceall green.Tests
Core: 3 new primitive tests. OCI: existing burst test unchanged. Download: new burst regression test. Full workspace green; both burst tests and the core tests verified non-flaky across 10 runs.
Follow-up
bunyip picks up nothing new here (internal refactor); the bunyip secret_env / acquire_concurrency_only switches from PSA-37/PSA-42 still await a dunite-core release.
#PSA-43