110 lines
11 KiB
Markdown
110 lines
11 KiB
Markdown
# Requirements: scheduler-controller-msg-gap
|
||
|
||
> Generated: 2026-05-11T01:34:00-07:00
|
||
> Updated: 2026-05-11T02:00:00-07:00
|
||
> Feature: scheduler-controller-msg-gap
|
||
> Status: Requirements Generated
|
||
|
||
## Overview
|
||
|
||
Analyze the codebase to find gaps in the scheduler's handling of controller messages — missing message types, unhandled edge cases, or incomplete message processing paths.
|
||
|
||
## Codebase Analysis Summary
|
||
|
||
The scheduler (`src/scheduler/src/handler.c`) receives controller messages through the `scheduler_req_handler` dispatcher, which handles two top-level opcodes:
|
||
|
||
- **OPCode_push** — carries ConfigData or Dataset (`datamsg`) messages. Raw `pushmsg` packets are reassembled into `datamsg` by the `vtask_entry()` assembly layer in `src/lib/xcectx.c` (lines 93–106); the handler never sees individual `pushmsg` fragments.
|
||
- **OPCode_notify** — carries NotifyData event messages
|
||
|
||
The controller (`src/controller/sched.c`) sends six NotifyData event types and two Data table types. The scheduler's handler has **6 gap locations** where the case is present but stubbed out or empty-bodied. The `Request_body_pushmsg` branch in `scheduler_req_handler` (which calls `sched_handle_jobpush`/`sched_handle_workerpush`) is dead code — it can never be reached because `vtask_entry` rewrites all `pushmsg` into `datamsg` before invoking the handler.
|
||
|
||
## Requirements
|
||
|
||
### Requirement 1: Resource data message handling
|
||
|
||
The scheduler SHALL process `Data_data_resources` dataset messages received from the controller. Upon receipt, the system SHALL update the internal resource catalog (resource name, type, flags, ordering type, interval) in the scheduler's resource manager (`sched->resmgr`), reconciling additions, removals, and modifications against the existing set.
|
||
|
||
The scheduler SHALL process `Data_data_resvals` dataset messages received from the controller. Upon receipt, the system SHALL update the shared resource value array (`sched->sharedInst`) with the new values indexed by position, and SHALL reset the `sharedInUse` tracking array for the next scheduling session.
|
||
|
||
**Acceptance criteria:**
|
||
- EARS-UB-1.1: WHEN the scheduler receives a dataset with `table == Data_data_resources`, THEN the system shall add or update each resource in `sched->resmgr`
|
||
- EARS-UB-1.2: WHEN the scheduler receives a dataset with `table == Data_data_resvals`, THEN the system shall update `sched->sharedInst` at each value's index position
|
||
- EARS-UB-1.3: WHEN either handler encounters a NULL element in the dataset rows, THEN the system shall skip that element and continue processing remaining rows
|
||
- EARS-UB-1.4: WHEN either handler encounters a memory allocation failure, THEN the system shall return `-ENOMEM` and free any partially allocated structures
|
||
|
||
### Requirement 2: Dead code removal — pushmsg handler branches
|
||
|
||
The scheduler SHALL remove the dead `Request_body_pushmsg` branch in `scheduler_req_handler` and the stub functions `sched_handle_jobpush` and `sched_handle_workerpush`. These paths can never execute because the `vtask_entry()` assembly layer in `src/lib/xcectx.c` rewrites all `pushmsg` packets into `datamsg` before invoking the request handler.
|
||
|
||
**Acceptance criteria:**
|
||
- EARS-UB-2.1: WHEN `scheduler_req_handler` is compiled, THEN the `Request_body_pushmsg` case and its two child branches (job/worker push) shall not exist
|
||
- EARS-UB-2.2: WHEN the scheduler is linked, THEN the symbols `sched_handle_jobpush` and `sched_handle_workerpush` shall not be present in the binary
|
||
|
||
### Requirement 3: NotifyData event handling for job updates
|
||
|
||
The scheduler SHALL process `NotifyData_data_schedUpdateJob` notify messages beyond the current trace-log-only behavior. Upon receipt, the system SHALL locate the job in `sched->jobs` by jobid, update the job's mutable fields (state, priority, queue, resource request) from the notify payload, and invoke `plugin_job_update` to notify plugins of the change.
|
||
|
||
**Acceptance criteria:**
|
||
- EARS-UB-3.1: WHEN the scheduler receives a notify with `event == NotifyData_data_schedUpdateJob`, THEN the system shall find the existing job by jobid and update its mutable fields
|
||
- EARS-UB-3.2: WHEN the jobid in the update notify does not match any existing job (i.e., the job was never pushed via the initial dataset bulk load), THEN the system shall return `-ENOENT` — jobs are created only via the `Data_data_schedjobs` dataset path, never via notify
|
||
- EARS-UB-3.3: WHEN the update payload carries job data that is NULL, THEN the system shall return `-EINVAL`
|
||
|
||
### Requirement 4: NotifyData event handling for queue updates
|
||
|
||
The scheduler SHALL process `NotifyData_data_schedUpdateQueue` notify messages from the controller. Upon receipt, the system SHALL locate the queue in `sched->queues` by name and update its status, priority, accept_interval, sched_delay, and resource request fields from the notify payload.
|
||
|
||
**Acceptance criteria:**
|
||
- EARS-UB-4.1: WHEN the scheduler receives a notify with `event == NotifyData_data_schedUpdateQueue`, THEN the system shall find the existing queue by name and update its mutable configuration fields
|
||
- EARS-UB-4.2: WHEN the queue name in the update notify does not match any existing queue (i.e., the queue was never loaded via the initial config push), THEN the system shall return `-ENOENT` — queues are created only via the `Conf4Sched` config path, never via notify
|
||
- EARS-UB-4.3: WHEN the update payload carries queue data that is NULL, THEN the system shall return `-EINVAL`
|
||
|
||
### Requirement 5: NotifyData event handling for resource value updates
|
||
|
||
The scheduler SHALL process `NotifyData_data_schedUpdateResvals` notify messages from the controller. Upon receipt, the system SHALL iterate the `xce_resval_list_t` payload, and for each resource value, update the per-worker `resvals` array on the named worker, matching by host name.
|
||
|
||
**Acceptance criteria:**
|
||
- EARS-UB-5.1: WHEN the scheduler receives a notify with `event == NotifyData_data_schedUpdateResvals`, THEN the system shall update each named worker's `resvals` array with the new values
|
||
- EARS-UB-5.2: WHEN a named host in the updates does not correspond to any known worker, THEN the system shall skip that update entry and continue processing remaining entries
|
||
- EARS-UB-5.3: WHEN the update payload carries zero resource values, THEN the system shall return 0 without modifying state
|
||
|
||
### Requirement 6: NotifyData event handling for job resource usage
|
||
|
||
The scheduler SHALL process `NotifyData_data_schedJobRusages` notify messages from the controller. Upon receipt, the system SHALL locate the job by jobid, store the resource usage data (`xce_sched_job_rusages_t`) on the job object, and invoke `plugin_job_rusage_update` to notify plugins of the usage change.
|
||
|
||
**Acceptance criteria:**
|
||
- EARS-UB-6.1: WHEN the scheduler receives a notify with `event == NotifyData_data_schedJobRusages`, THEN the system shall store the usage data on the matching job
|
||
- EARS-UB-6.2: WHEN the jobid in the update does not match any existing job, THEN the system shall return `-ENOENT` without modifying state
|
||
- EARS-UB-6.3: WHEN the rusage payload is NULL, THEN the system shall return `-EINVAL`
|
||
|
||
### Requirement 7: Error handling consistency
|
||
|
||
The scheduler SHALL return meaningful error codes from all message handlers that enable the controller to distinguish between transient failures (ENOMEM) and permanent protocol errors (EINVAL, ENOENT). The scheduler's main loop in `sched_update()` SHALL log a WARN-level message when a handler returns a non-zero error code, including the offending opcode and sub-type for operational debugging.
|
||
|
||
**Acceptance criteria:**
|
||
- EARS-UB-7.1: WHEN a handler returns a non-zero error code, THEN `sched_update()` shall emit a WARN log including the `xce_sched_op_t` value and the error code
|
||
- EARS-UB-7.2: WHEN an unknown notify event type is received, THEN the handler shall return `-EINVAL` (already implemented — verify non-regression)
|
||
- EARS-UB-7.3: WHEN a push message arrives with an unknown `body_which` tag, THEN the handler shall return `-EINVAL` (already implemented — verify non-regression)
|
||
|
||
### Requirement 8: Human-readable message type names in logs
|
||
|
||
The scheduler SHALL log message type identifiers using symbolic names rather than numeric values. The existing helpers in `src/lib/helper.c` — `xce_request_op_name()`, `xce_request_msg_name()`, and `xce_dataset_table()` — already provide name lookups for OPCode, Request body tag, and Data table type. A new `xce_notify_event_name(int)` function SHALL be added to cover the NotifyData event type enum. All TRACE, DEBUG, INFO, and WARN messages in `handler.c` that reference these enums SHALL use these name-lookup functions instead of printing numeric values.
|
||
|
||
**Acceptance criteria:**
|
||
- EARS-UB-8.1: WHEN `scheduler_req_handler` logs a message that includes an opcode, THEN the log shall call `xce_request_op_name()` to show the symbolic name (e.g., `"push"`) rather than the numeric value
|
||
- EARS-UB-8.2: WHEN `sched_handle_dataset` logs a message that includes a data table type, THEN the log shall call `xce_dataset_table()` to show the symbolic name (e.g., `"schedjobs"`) rather than the numeric value (currently `TRACE("%s table = %d", ...)`)
|
||
- EARS-UB-8.3: WHEN `sched_handle_notify` logs a message that includes a notify event type, THEN the log shall call `xce_notify_event_name()` to show the symbolic name rather than the numeric value
|
||
- EARS-UB-8.4: WHEN `xce_notify_event_name()` receives a numeric value that does not correspond to a known NotifyData enum constant, THEN it shall return `"UNKNOWN(%d)"` with the numeric value substituted (matching the pattern used by the existing helpers)
|
||
- EARS-UB-8.5: WHEN `sched_update()` emits a WARN log for a handler error (per Requirement 7), THEN the log shall include symbolic names via the appropriate helper function
|
||
|
||
## Non-Requirements
|
||
|
||
The following areas are intentionally excluded from this specification:
|
||
- **New protocol message types** — only existing, already-defined message types in `controller.capnp` are in scope
|
||
- **Controller-side changes** — only the scheduler's inbound message handling is in scope
|
||
- **Plugin implementation details** — plugin update functions are called but not modified
|
||
- **Bulk (Dataset) job/worker push already works** — the `Data_data_schedjobs` and `Data_data_schedworkers` cases in `sched_handle_dataset` already delegate to `sched_on_jobs`/`sched_on_workers`
|
||
- **`pushmsg` handler path** — the `Request_body_pushmsg` branch in `scheduler_req_handler` and the functions `sched_handle_jobpush`/`sched_handle_workerpush` are dead code; the `vtask_entry()` assembly layer in `src/lib/xcectx.c` rewrites all `pushmsg` into `datamsg` before the handler is called, so incremental push handling is never needed
|
||
|
||
## Next Step
|
||
|
||
Run `/kiro:spec-design scheduler-controller-msg-gap` to proceed to design phase.
|