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

224 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Implementation Tasks: resval-id-decoupling
> Generated: 2026-05-12T07:45:00-07:00
> Feature: resval-id-decoupling
> Status: Tasks Generated
## Task Overview
7 major tasks, 19 sub-tasks. All 6 requirements covered.
Dependencies: Task 1 must complete first (headers + schema unblock everything).
Tasks 2 and 3 can proceed in parallel after Task 1.
Tasks 4, 5, 6 can proceed in parallel after Tasks 2 and 3.
Task 7 last.
---
## Tasks
### 1. Update shared headers and capnp schema
Change the wire type and C struct types that carry resource values across subsystem
boundaries. This is the structural foundation — all downstream tasks depend on these
types compiling correctly.
- [x] 1.1 In `src/schema/controller.capnp`, change `Worker.resvals @5` and
`Conf4Sched.resvals @6` from `List(ValueWithIdx)` to `List(NameValue)`. Preserve
field ordinal numbers; only the element type changes.
_Requirements: 1, 2, 3, 4_
- [x] 1.2 In `src/include/xce/types.h`, change `xce_worker_t.resvals_to_sched` from
`xce_val_with_idx_t**` to `xce_name_val_t**`.
_Requirements: 2, 3_
- [x] 1.3 In `src/include/typemap.h`, change `xce_conf4sched_t.resvals` from
`xce_val_with_idx_t**` to `xce_name_val_t**`.
_Requirements: 1, 4_
- [x] 1.4 Run `nix develop --command ninja -C src/build` to regenerate
`controller.capnp.[ch]`. Confirm the generated `encode_Conf4Sched` and
`decode_Conf4Sched` now call `encode_NameValue_list` / `decode_NameValue_list`
instead of their `ValueWithIdx` counterparts. Expect compiler errors at this stage
from old call sites — that is expected and resolved in subsequent tasks.
---
### 2. (P) Replace `free_resval_with_idx_list` with `free_name_val_list`
Swap the heap-cleanup utility function to match the new element type. Old callers in
the controller will be updated in Task 4.
- [x] 2.1 In `src/lib/utils.c`, add `free_name_val_list(xce_name_val_t*** vals, int count)`:
iterate the array, free each entry's `name`, free `val->u.svalue` if string-typed,
free `val`, free the entry, then null and free the array pointer. Mirror the structure
of the existing `free_resval_with_idx_list`.
- [x] 2.2 In `src/include/utils.h`, remove the `free_resval_with_idx_list` declaration
and add `extern void free_name_val_list(xce_name_val_t***, int);`.
- [x] 2.3 In `src/lib/utils.c`, delete the `free_resval_with_idx_list` implementation.
_Requirements: 5_
---
### 3. (P) Add `collect_resval` and remove `collect_resval_with_idx`
Replace the index-keyed collector in the controller with a name-keyed one. The key
design inversion: iterate `resmgr` (names) rather than the `zarray_t` (slots), using
`r->idx` to look up values. This guarantees every emitted record carries a valid name.
- [x] 3.1 In `src/controller/dataex.c`, add `collect_resval(var resmgr, zarray_t* array, xlist_t* l)`:
acquire a read lock on `resmgr`, iterate with `iter_make`/`iter_next`/`iter_destroy`,
for each `xce_resource_t* r` call `zarray_get(array, r->idx)` to get the value (skip
if NULL), allocate an `xce_name_val_t`, copy name (strdup) and value (strdup svalue or
memcpy), store in the list. Release the resmgr lock. Return `l->count`. The array lock
is the caller's responsibility (consistent with old pattern).
_Requirements: 1, 2, 5_
- [x] 3.2 In `src/controller/dataex.c`, rewrite `collect_shared_resvals` to lock
`c->sharedinst.lock`, call `collect_resval(c->resmgr, &c->sharedinst, l)`, then
unlock. The unused `fn` parameter is retained for signature consistency.
_Requirements: 1_
- [x] 3.3 In `src/controller/dataex.c`, update `collect_resvals_workers` to accept
`var resmgr` as a new first parameter. Replace the `collect_resval_with_idx` call with
`mylock_lock(&w->resvals.lock)` / `collect_resval(resmgr, &w->resvals, &lst)` /
`mylock_unlock`. Update the call site in `collect_workers` to pass `c->resmgr`.
_Requirements: 2_
- [x] 3.4 In `src/controller/dataex.c`, delete both `collect_resval_with_idx_` (static)
and `collect_resval_with_idx`. In `src/controller/include/cluster.h`, remove the
`collect_resval_with_idx` declaration.
_Requirements: 5_
---
### 4. (P) Update controller call sites
Update all controller sites that populate or clean up `resvals_to_sched` /
`conf4sched->resvals` to use the new type and free function. Tasks 2 and 3 must be
complete before this task.
- [x] 4.1 In `src/controller/sched.c` — `xcesched_push_configs`: change the cast from
`(xce_val_with_idx_t**)` to `(xce_name_val_t**)` when assigning `xreslist.data` to
`conf4sched->resvals`, and replace `free_resval_with_idx_list` with
`free_name_val_list`.
_Requirements: 1_
- [x] 4.2 In `src/controller/sched.c` — `xcesched_push_workerlist` and its worker-loop
cleanup: add `mylock_lock`/`mylock_unlock` around `collect_resval`, change cast to
`(xce_name_val_t**)`, replace all `free_resval_with_idx_list` calls with
`free_name_val_list`.
_Requirements: 2_
- [x] 4.3 In `src/controller/sched.c:226`, `src/controller/reply.c:66`, and
`src/controller/opget.c:128`, replace each `free_resval_with_idx_list` call with
`free_name_val_list`.
_Requirements: 5_
- [x] 4.4 In `src/controller/apiserver.c` — `apiserver_worker_change`: add
`mylock_lock`/`mylock_unlock` around `collect_resval`, change cast to
`(xce_name_val_t**)`, replace `free_resval_with_idx_list` with `free_name_val_list`
at both cleanup sites (lines 51 and 397–399).
_Requirements: 3_
---
### 5. (P) Update scheduler — shared resource value initialisation
Change `sched_init_sharedInst` to resolve resource values by name via the scheduler's
own resmgr instead of using the raw index received from the controller. Task 1 must be
complete before this task.
- [x] 5.1 In `src/scheduler/src/scheduler.c` — `sched_init_sharedInst`: replace the
`idx`-direct loop with a name-lookup loop. For each `xce_name_val_t* nv` in
`sched->config->resvals`: skip if `nv` or `nv->name` is NULL; call
`key_find(sched->resmgr, nv->name, &r)`; if not found emit `WARN` and continue; then
`MOVE_PTR(val, nv->val)` and `zarray_put(&sched->sharedInst, r->idx, val)`. Do not
change the call order in `sched_init_config` — `sched_init_resources` must remain
before `sched_init_sharedInst`.
_Requirements: 1, 6_
---
### 6. (P) Update scheduler — per-worker resource value initialisation
Change `make_sched_worker` to resolve worker resource values by name. Task 1 must be
complete before this task.
- [x] 6.1 In `src/scheduler/src/schedobj.c` — `make_sched_worker`: replace the
`idx`-direct loop with a name-lookup loop. For each `xce_name_val_t* nv` in
`w->resvals_to_sched`: skip if `nv` or `nv->name` is NULL; call
`key_find(sched->resmgr, nv->name, &r)`; if not found emit `WARN` and continue; then
`MOVE_PTR(val, nv->val)` and `zarray_put(&worker->resvals, r->idx, val)`. The
existing `sched` pointer (cast from `void* arg`) is already available at the top of
the function.
_Requirements: 2, 6_
---
### 7. Update Go API server to consume worker resource values
Update the Go API server frontend to read `resvals_to_sched` (now `xce_name_val_t**`)
from received worker data and expose resource values in the `HostInfo` model. Previously
the Go layer ignored this field entirely.
- [x] 7.1 In `src/frontend/apiserver/models/hosts.go`, add
`ResourceValues []models.ResourceDistributionInfo` (or
`ResourceValues []ResourceDistributionInfo` if within the same package) to `HostInfo`.
_Requirements: 3_
- [x] 7.2 In `src/frontend/apiserver/backend/convert_pure.go`, add a `resvals` field
(`[]models.ResourceDistributionInfo`) to `rawWorkerData`, and update `rawWorkerToModel`
to assign `info.ResourceValues = r.resvals`.
_Requirements: 3_
- [x] 7.3 In `src/frontend/apiserver/backend/convert.go`, add
`cNameValToWorkerResval(workerName string, nv *C.xce_name_val_t) *models.ResourceDistributionInfo`:
return nil if `nv` or `nv.val` is nil (with a WARN log); set `ResourceName` from
`nv.name`, `Location` from `workerName`, `IsDynamic: true`; decode the value type
using the same `xce_val_which` switch as `cResvalToDistribution`.
_Requirements: 3_
- [x] 7.4 In `src/frontend/apiserver/backend/convert.go`, update `cWorkerToModel` to
iterate `worker.nresvals_to_sched` entries in `worker.resvals_to_sched`, call
`cNameValToWorkerResval` for each, collect non-nil results, and store them in
`rawWorkerData.resvals`.
_Requirements: 3_
---
### 8. Build, verify, and clean up
Confirm the full system compiles and passes tests with no regressions. All prior tasks
must be complete.
- [x] 8.1 Run a full clean build: `nix develop --command bash -c "cd src && ninja -C build"`.
Resolve any remaining compiler errors (expected: none if tasks 1–7 complete). Confirm
`controller.capnp.[ch]` uses `NameValue` codecs for both `Conf4Sched.resvals` and
`Worker.resvals`.
- [x] 8.2 Run the scheduler and controller test suites:
`nix develop --command bash -c "cd src/frontend && make test"` and any C-level tests
under `src/lib/testsuite/`. Confirm all tests pass. Note: `xcecli/common/output`
failure (`undefined: parseJobTime`) is pre-existing and unrelated to this feature.
- [x] 8.3 Verify no remaining references to `collect_resval_with_idx` or
`free_resval_with_idx_list` in `src/` (excluding comments or git history):
`grep -r "collect_resval_with_idx\|free_resval_with_idx_list" src/`. Expected: zero
matches.
_Requirements: 5_
---
## Requirements Coverage
| Requirement | Tasks |
|------------|-------|
| 1 | 1.1, 1.3, 3.2, 4.1, 5.1 |
| 2 | 1.1, 1.2, 3.3, 4.2, 4.3, 6.1 |
| 3 | 1.1, 1.2, 4.4 |
| 4 | 1.1, 1.3 |
| 5 | 2.1, 2.2, 2.3, 3.4, 4.3, 7.3 |
| 6 | 5.1, 6.1 |