resource_limits: read the override map once per SSE scan

`container_view::build_all` renders every container on every scan, and
each agent's row resolved its limits through `effective()`, which reads
and parses `resource-limits.json` from disk. That is one file read per
agent per scan of a file that is identical for all of them.

Split the resolution in two: `effective_from` takes an already-loaded
map, and `effective` keeps the read-then-resolve shape for the
single-agent callers (`write_dropins`, which runs once per spawn and
rebuild and has no map to hand). `build_all` now loads the map once at
the top — the same treatment `topology::read()` already gets there —
and calls `effective_from` per agent.

No behaviour change: the fallback matrix lives in `resolve`, which both
paths still go through, and its tests are untouched.

The now-redundant `limits_for` is gone; `effective_from` covers its one
caller.
This commit is contained in:
atlas 2026-07-26 14:56:36 +02:00
commit c149963917
2 changed files with 28 additions and 9 deletions

View file

@ -88,6 +88,10 @@ pub async fn build_all(hive: &crate::coordinator::HiveEnv) -> Vec<ContainerView>
// Empty / absent topology.json → every agent root-level (safe
// degradation for fresh installs that haven't run sync_agents yet).
let topology = crate::topology::read();
// Same once-per-scan treatment as the topology map: the override file
// is read here and resolved per agent below, rather than re-read for
// every container on every SSE scan.
let limits = crate::resource_limits::read();
let mut out = Vec::new();
for c in &raw {
let Some(logical) = c.strip_prefix(AGENT_PREFIX) else {
@ -123,7 +127,8 @@ pub async fn build_all(hive: &crate::coordinator::HiveEnv) -> Vec<ContainerView>
None
};
let paused = Coordinator::is_paused(&logical);
let (cpu_quota, memory_max) = crate::resource_limits::effective(
let (cpu_quota, memory_max) = crate::resource_limits::effective_from(
&limits,
logical.as_str(),
&hive.agent_cpu_quota,
&hive.agent_memory_max,