myxce/.kiro/specs/resval-id-decoupling/requirements.md

9.2 KiB

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.