Background
PR #4472 introduced MODULE_CACHE_METRICS as a process-global static to share metrics between two components that live on opposite sides of an architectural boundary:
- Writers (
ModuleCache::insert / evict_to_budget / remove) — owned by RuntimePool, behind the contract-handler channel.
- Reader (
ring.rs:1074) — the Ring snapshot task, which has no channel or reference to RuntimePool.
This mirrors the existing TRANSPORT_METRICS static and is correct given the single-RuntimePool-per-process production invariant. The static was the right call for the PR scope.
Problem
Process-global statics make test isolation harder: labeled caches in different unit tests share the same gauge pair, so parallel tests can observe each other's metric state. This is the same problem class that TRANSPORT_METRICS has.
Proposed refactor
Replace the static with an Arc<ModuleCacheMetrics> threaded through the call graph:
- Construct
Arc<ModuleCacheMetrics> at node startup (in Node::build or equivalent).
- Pass it into
RuntimePool::new → stored on each ModuleCache via ModuleCache::with_label.
- Store the same
Arc in RouterSnapshotInfo or Ring so the snapshot task can call .snapshot() from it.
Estimated scope: ~4 function signature changes (RuntimePool::new, ModuleCache::with_label, snapshot-state construction, and one or two call sites).
Acceptance criteria
References
Background
PR #4472 introduced
MODULE_CACHE_METRICSas a process-globalstaticto share metrics between two components that live on opposite sides of an architectural boundary:ModuleCache::insert/evict_to_budget/remove) — owned byRuntimePool, behind the contract-handler channel.ring.rs:1074) — theRingsnapshot task, which has no channel or reference toRuntimePool.This mirrors the existing
TRANSPORT_METRICSstatic and is correct given the single-RuntimePool-per-process production invariant. The static was the right call for the PR scope.Problem
Process-global statics make test isolation harder: labeled caches in different unit tests share the same gauge pair, so parallel tests can observe each other's metric state. This is the same problem class that
TRANSPORT_METRICShas.Proposed refactor
Replace the static with an
Arc<ModuleCacheMetrics>threaded through the call graph:Arc<ModuleCacheMetrics>at node startup (inNode::buildor equivalent).RuntimePool::new→ stored on eachModuleCacheviaModuleCache::with_label.ArcinRouterSnapshotInfoorRingso the snapshot task can call.snapshot()from it.Estimated scope: ~4 function signature changes (
RuntimePool::new,ModuleCache::with_label, snapshot-state construction, and one or two call sites).Acceptance criteria
MODULE_CACHE_METRICSstatic removed.ModuleCacheMetricsconstructed once and threaded asArcthroughRuntimePooland theRingsnapshot path.ModuleCachecreate isolated metric instances without cross-talk.References
module_cache.rs:267)TRANSPORT_METRICS— the existing static this mirrors; a follow-up to that one would be a natural pairing.