95 lines
9.2 KiB
Markdown
95 lines
9.2 KiB
Markdown
# Requirements: resval-id-decoupling
|
|
|
|
> Generated: 2026-05-12T06:52:00-07:00
|
|
> Updated: 2026-05-12T07:10:00-07:00
|
|
> Feature: resval-id-decoupling
|
|
> Status: Requirements Generated
|
|
|
|
## Overview
|
|
|
|
The controller passes resource values to the scheduler (initial config push) and to the API server (worker data) using `xce_val_with_idx_t`, a struct carrying a numeric array-slot index. The scheduler and API server then store values at that same index in their own `zarray_t` stores. This works only when both components assign the same slot number to each resource — an assumption that holds when resource registration order is strictly identical but is not enforced by any contract and will silently produce wrong values if it breaks.
|
|
|
|
The ongoing update path (`Data_data_resvals` dataset, `xce_resval_t` with `name` field) already resolves this correctly via name-based lookup in the receiver's own resmgr. The goal of this feature is to apply the same name-keyed approach uniformly across all resource-value transfer paths, eliminating the hidden index-identity assumption.
|
|
|
|
## Codebase Analysis Summary
|
|
|
|
Three distinct paths currently transfer resource values between components:
|
|
|
|
**Path A — Shared resvals in initial config push** (`src/controller/sched.c:118-120`)
|
|
- `collect_shared_resvals()` → `collect_resval_with_idx(&c->sharedinst, ...)` emits `{idx, val}` pairs where `idx` is the controller's `sharedinst` zarray slot (= controller resource `idx`).
|
|
- Scheduler receives via `xce_conf4sched_t.resvals` (`xce_val_with_idx_t**`) and stores directly at the same index: `zarray_put(&sched->sharedInst, idx, val)` (`src/scheduler/src/scheduler.c:583`).
|
|
- **Bug**: If `resource->idx` differs between controller and scheduler (different insertion order into each component's independent resmgr), values land in the wrong slot.
|
|
|
|
**Path B — Worker resvals to scheduler** (`src/controller/sched.c:442-444`, `src/controller/apiserver.c:367-369`)
|
|
- `collect_resval_with_idx(&w->host.resvals, ...)` emits `{idx, val}` from the controller's per-worker resvals zarray (slot = controller resource `idx`).
|
|
- Scheduler stores at the same slot: `zarray_put(&worker->resvals, idx, val)` (`src/scheduler/src/schedobj.c:279`).
|
|
- Later, `resource.c` indexes `worker->resvals` using the scheduler's own `residx` values — a mismatch if indices differ.
|
|
|
|
**Path C — `Data_data_resvals` dataset update** (already correct)
|
|
- Uses `xce_resval_t` (name + host + val). Scheduler looks up `r = key_find(sched->resmgr, rv->name)` then uses `r->idx` (its own index): `zarray_put(&sched->sharedInst, r->idx, rv->val)` (`src/scheduler/src/scheduler.c:784`).
|
|
- No index-identity assumption. This is the target pattern.
|
|
|
|
The fix must align Paths A and B with Path C's name-based resolution approach. The existing `xce_name_val_t` type (`src/include/xce/types.h:43`) already provides the right shape for shared resvals (name + val). The `xce_resval_t` type already provides the shape for per-host/worker resvals (name + host + val).
|
|
|
|
## Requirements
|
|
|
|
### Requirement 1: Name-keyed shared resource value transfer in initial config
|
|
|
|
The scheduler SHALL receive shared resource values from the controller as name-keyed records (resource name + value) rather than as array-slot-indexed records.
|
|
|
|
Upon receiving the initial config push, the scheduler SHALL resolve each resource value to its own slot index by looking up the resource name in its own resource manager (`sched->resmgr`), then store the value at the resolved index in `sched->sharedInst`.
|
|
|
|
The scheduler SHALL log a warning and skip (not crash or silently corrupt) any resource value for which the resource name is not found in its resource manager.
|
|
|
|
**Acceptance criteria:**
|
|
- EARS-R1-1: WHEN the controller sends an initial config push (`ConfigData_data_schedconfig`) containing shared resource values, THEN each resource value SHALL be identified by resource name, not by a numeric array slot index.
|
|
- EARS-R1-2: WHEN the scheduler processes a shared resource value record whose name matches a resource in `sched->resmgr`, THEN the scheduler SHALL store the value at the index assigned by its own resmgr (`r->idx`).
|
|
- EARS-R1-3: WHEN the scheduler processes a shared resource value record whose name does not match any resource in `sched->resmgr`, THEN the scheduler SHALL emit a warning log and skip that record without modifying `sched->sharedInst`.
|
|
- EARS-R1-4: WHEN an existing system running Path C updates (`Data_data_resvals`) works correctly, THEN after this change the initial-config path SHALL produce the same `sched->sharedInst` state as Path C would for the same resource values.
|
|
|
|
### Requirement 2: Name-keyed per-worker resource value transfer to scheduler
|
|
|
|
The scheduler SHALL receive per-worker resource values from the controller as name-keyed records (resource name + value) rather than as array-slot-indexed records.
|
|
|
|
Upon receiving worker data, the scheduler SHALL resolve each worker resource value to its own slot index by looking up the resource name in its resource manager, then store the value at the resolved index in the worker's `resvals` zarray.
|
|
|
|
The scheduler SHALL log a warning and skip any worker resource value whose resource name is not found.
|
|
|
|
**Acceptance criteria:**
|
|
- EARS-R2-1: WHEN the controller sends worker data containing per-worker resource values, THEN each resource value SHALL be identified by resource name, not by a numeric array slot index.
|
|
- EARS-R2-2: WHEN the scheduler builds a `sched_worker` from received worker data, THEN it SHALL resolve each resource value name to the scheduler's own `r->idx` before calling `zarray_put(&worker->resvals, ...)`.
|
|
- EARS-R2-3: WHEN a resource name in a worker's resource values is unknown to the scheduler's resmgr, THEN the scheduler SHALL log a warning and skip that entry without aborting worker construction.
|
|
- EARS-R2-4: WHILE the scheduler is running and a resource is added or removed from the resource catalog, THEN subsequently received worker data SHALL correctly resolve resource values using the updated resmgr, with no stale index cached from before the change.
|
|
|
|
### Requirement 3: Name-keyed per-worker resource value transfer to API server
|
|
|
|
The API server SHALL receive per-worker resource values from the controller as name-keyed records (resource name + value) so that its own resource catalog lookup can resolve values independently of the controller's internal index assignment.
|
|
|
|
**Acceptance criteria:**
|
|
- EARS-R3-1: WHEN the controller sends worker data to an API server connection, THEN per-worker resource values SHALL be transmitted using resource names as keys.
|
|
- EARS-R3-2: WHEN the API server (`src/frontend/apiserver`) converts worker resource values for its models (e.g., `cResvalToDistribution`), THEN it SHALL be able to match values to resources by name without assuming any particular numeric index.
|
|
|
|
### Requirement 4: Backward compatibility with the `Data_data_resvals` update path
|
|
|
|
The name-keyed changes to the initial config and worker data paths SHALL NOT alter the behavior of the existing `Data_data_resvals` dataset update path (Path C), which is already name-keyed.
|
|
|
|
**Acceptance criteria:**
|
|
- EARS-R4-1: WHEN the scheduler processes a `Data_data_resvals` dataset message, THEN the behavior SHALL be identical before and after this change.
|
|
- EARS-R4-2: WHEN the `xce_conf4sched_t` struct is updated to use name-keyed resval records, THEN all callers that populate or consume this struct SHALL be updated consistently (controller, scheduler, and any serialization/deserialization layer in `libxce`).
|
|
|
|
### Requirement 5: Removal of the index-keyed `collect_resval_with_idx` call sites
|
|
|
|
The `collect_resval_with_idx` function (or its callers) SHALL be updated or replaced so that no code path transmits resource values indexed solely by a numeric array slot without an accompanying resource name.
|
|
|
|
**Acceptance criteria:**
|
|
- EARS-R5-1: WHEN this feature is complete, THEN no code path that crosses a subsystem boundary (controller → scheduler, controller → API server) SHALL rely on the receiving subsystem's `zarray_t` slot indices matching the sending subsystem's slot indices.
|
|
- EARS-R5-2: WHEN `collect_resval_with_idx` is no longer needed for cross-subsystem transfer, THEN it SHOULD be removed or restricted to intra-subsystem use only, with a comment explaining its scope.
|
|
|
|
### Requirement 6: No regression in resource value correctness
|
|
|
|
The scheduler's scheduling decisions SHALL produce the same resource value lookups after this change as they did when indices happened to be consistent, and SHALL produce correct results when indices are inconsistent (where the old code would silently corrupt scheduling state).
|
|
|
|
**Acceptance criteria:**
|
|
- EARS-R6-1: WHEN the controller and scheduler register resources in a different order (causing their resmgr index assignments to differ), THEN `sched->sharedInst` SHALL still contain the correct value for each resource after receiving the initial config push.
|
|
- EARS-R6-2: WHEN the controller and scheduler register resources in the same order, THEN the behavior of the scheduler SHALL be identical to the current behavior.
|
|
- EARS-R6-3: WHEN worker resource values are applied during a scheduling cycle, THEN `calc_wanted_global_resvals` and `calc_wanted_host_resvals` SHALL retrieve values from `sharedInst` and `worker->resvals` using the scheduler's own resource indices, unaffected by the controller's index ordering.
|