224 lines
9.5 KiB
Markdown
224 lines
9.5 KiB
Markdown
# 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 |
|