feat(scheduler-core): define new event payload types (task 7.2)

Adds JobStateChangeEvent (jobid/oldState/newState/exitCode) and
JobUpdateEvent (jobid/changedFields/job: Job) to controller.capnp,
matching design.md's spec verbatim. JobUpdateEvent.job reuses the
existing full 12-field Job/xce_job_t record, verified distinct from
the narrower SchedJob struct sharing the same mapname.

Extends ReplayEvent.body's union (task 7.1) with jobStateChange@10/
jobUpdate@11 -- the only two valid next ordinals, since capnp requires
strictly sequential ordinals with no gaps across a struct and task
7.1 deliberately stopped at @9. Existing @0-@9 fields and every other
struct in the schema are byte-identical.

Deep round-trip tests in test_e2e_capnp.c exercise every field with
non-default values, including the 3-level nested Job substructs
(submitData/allocs/pidinfo/pendreason). JOB_F_* bitmask bit values
deliberately left undefined -- a later task's job, not this
schema-only one's.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019dw5WnN3DXStaEaPYfACU1
This commit is contained in:
Rongsong Shen 2026-08-04 10:17:57 +00:00
parent 68a6196517
commit 755230705c
Signed by: rshen
SSH key fingerprint: SHA256:8Vf2pZ3h6rJa7EhGK+WaAQ9Mta/apZvteW6g9U/WKKk
4 changed files with 295 additions and 4 deletions

View file

@ -1041,12 +1041,32 @@ struct SnapshotEntry $C.mapname("replay_snapshot_entry_t") {
data @1: SnapshotData; # full core state
}
# task 7.2 (Req 5 AC 20): the two genuinely new event payload types --
# every other ReplayEvent.body variant reuses a pre-existing wire struct
# (see ReplayEvent's comment block below). jobStateChange/jobUpdate are
# added as ReplayEvent.body union members at ordinals 10/11 below.
struct JobStateChangeEvent $C.mapname("job_state_change_event_t") {
jobid @0: UInt64;
oldState @1: UInt32 $C.mapname("old_state");
newState @2: UInt32 $C.mapname("new_state");
exitCode @3: Int32 $C.mapname("exit_code");
}
struct JobUpdateEvent $C.mapname("job_update_event_t") {
jobid @0: UInt64;
# bitmask: JOB_F_PRIORITY, JOB_F_QUEUE, JOB_F_RESREQ -- no JOB_F_* constants
# exist anywhere in the codebase yet (confirmed by task 5.1's grep); concrete
# bit assignments are task 9+ event-translation/recording code's job, not
# this schema-only task's.
changedFields @1: UInt32 $C.mapname("changed_fields");
job @2: Job; # full updated record; reuses existing Job struct
}
# ReplayEvent.body reuses 7 pre-existing wire structs verbatim (Conf4Sched,
# SchedJobData, WorkerData, ResourceData, ResValList x2, QueueConf,
# SchedJobRusages -- verified present in controller.capnp, research.md) plus
# a Void end-of-recording marker. jobStateChange/jobUpdate (task 7.2) are
# added later as new union members at ordinals 10/11, once
# JobStateChangeEvent/JobUpdateEvent exist.
# a Void end-of-recording marker, plus the two new JobStateChangeEvent/
# JobUpdateEvent structs (task 7.2) above.
struct ReplayEvent $C.mapname("replay_event_t") {
ts @0: UInt64; # logical time
body :union $C.mapuniontag("body_which") {
@ -1059,6 +1079,8 @@ struct ReplayEvent $C.mapname("replay_event_t") {
queueUpdate @7: QueueConf $C.mapname("queue_update");
jobRusage @8: SchedJobRusages $C.mapname("job_rusage");
endSession @9: Void; # recording stop marker
jobStateChange @10: JobStateChangeEvent $C.mapname("job_state_change");
jobUpdate @11: JobUpdateEvent $C.mapname("job_update");
}
}