fix(scheduler): record events before the core applies them (bug-1852)
The recorder encoded each controller event batch after xce_core_push_events() had applied it, and applying moves payload fields out of the events: a WORKERS_PUSH's resvals (core_apply_worker_resvals MOVE_PTR), a JOBS_PUSH's allocs, a JOB_RUSAGE's rusages, and a CONFIG_PUSH's shared resvals (sched_apply_pending_config recorded after sched_init_config). Recordings silently lost exactly those fields -- a worker's resval names were written with NULL values, so --sim-verify replayed "no slots" and turned 3 live DISPATCHes into PENDs. driver.c now records the batch before the push; the periodic in-stream SnapshotEntry moves out of sched_record_write_events() into new sched_record_checkpoint_after_apply(), called after the push so a checkpoint still reflects the events written ahead of it. The config push is likewise recorded before sched_init_config(). Regression test: test_recorded_workers_push_keeps_resval_values (RED: recorded value NULL; GREEN after). Periodic-checkpoint tests updated to the write-then-checkpoint contract. meson test 109/109; 25 live soak recordings replay with 0 mismatches. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ca4db13a79
commit
9c02184fb4
10 changed files with 258 additions and 33 deletions
|
|
@ -225,19 +225,14 @@ extern int sched_record_stop(xce_scheduler_t* sched);
|
|||
* returned; the caller (driver.c) does not need to react further -- normal
|
||||
* scheduling continues either way (Req 5 AC 10, "Error handling").
|
||||
*
|
||||
* Periodic checkpoint (Req 5 AC 11, task 9.3): after the whole batch's
|
||||
* events are written, if `sched->record_snapshot_interval > 0` and the
|
||||
* (cumulative, since recording started) `sched->record_event_count` has
|
||||
* just landed exactly on a multiple of it, a fresh `SnapshotEntry` message
|
||||
* is appended (via recording.c's shared write_snapshot_entry(), the SAME
|
||||
* builder sched_record_start() uses for the initial one -- DRY, never
|
||||
* duplicated). `record_snapshot_interval == 0` disables this entirely.
|
||||
* Checked ONCE per call against the post-batch count, not once per
|
||||
* multiple crossed within one large batch -- see recording_events.c's own
|
||||
* comment on sched_record_write_events() for the full boundary-semantics
|
||||
* rationale. A checkpoint write failure disables recording via
|
||||
* sched_record_abort_on_error(), the exact same path as any other
|
||||
* recording write failure -- never special-cased.
|
||||
* Call BEFORE the batch is applied to the core (bug-1852): applying moves
|
||||
* payload fields out of the events (core_apply_worker_resvals()'s
|
||||
* MOVE_PTR of each resval, a JOBS_PUSH's allocs, a JOB_RUSAGE's rusages,
|
||||
* a CONFIG_PUSH's shared resvals), so an event encoded afterwards is
|
||||
* missing exactly those fields and replays differently. The periodic
|
||||
* checkpoint is a separate step, sched_record_checkpoint_after_apply()
|
||||
* below, because a SnapshotEntry must reflect the events written ahead
|
||||
* of it.
|
||||
*
|
||||
* Concurrency (task 9.4 fix round): the per-event increment of
|
||||
* `sched->record_event_count` takes `sched->record_lock` (scheduler.h's
|
||||
|
|
@ -249,6 +244,25 @@ extern int sched_record_stop(xce_scheduler_t* sched);
|
|||
extern int sched_record_write_events(xce_scheduler_t* sched,
|
||||
xce_core_event_t* events, int n);
|
||||
|
||||
/*
|
||||
* sched_record_checkpoint_after_apply - periodic checkpoint (Req 5 AC 11,
|
||||
* task 9.3), called AFTER the batch just recorded by
|
||||
* sched_record_write_events() has been applied to the core. If
|
||||
* `sched->record_snapshot_interval > 0` and the (cumulative, since
|
||||
* recording started) `sched->record_event_count` has just landed exactly
|
||||
* on a multiple of it, a fresh `SnapshotEntry` message is appended (via
|
||||
* recording.c's shared write_snapshot_entry(), the SAME builder
|
||||
* sched_record_start() uses for the initial one). `record_snapshot_interval
|
||||
* == 0` disables this entirely. Checked ONCE per call against the
|
||||
* post-batch count, not once per multiple crossed within one large batch
|
||||
* -- see recording_events.c's own comment for the full boundary-semantics
|
||||
* rationale. A checkpoint write failure disables recording via
|
||||
* sched_record_abort_on_error(), the exact same path as any other
|
||||
* recording write failure. Same zero-cost no-op gate as
|
||||
* sched_record_write_events().
|
||||
*/
|
||||
extern int sched_record_checkpoint_after_apply(xce_scheduler_t* sched);
|
||||
|
||||
/*
|
||||
* sched_record_session_ctx_t - opaque per-round accumulator for the
|
||||
* decisions a recording session collects between
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue