fix(scheduler): sim mode force-dispatched recorded decisions past live capacity (bug-1836, bug-1838)
User-reported: replaying a captured session dispatched 44 single-slot jobs onto a 22-slot host. Root cause traced through two layers: - bug-1836: sim_reconcile_unaccounted_jobs() (the "Recorded-Decision Reconciliation" backstop) force-applied any recorded DISPATCH decision it found, with zero live capacity check. Added sim_reconciled_alloc_fits_capacity(), reusing the same sched_check_host_satisfy()/sched_check_shared_satisfy() admission checks the live picker/allocator path already uses. - bug-1838: even with that gate, reconciliation still preempted every freshly-PEND job before the live picker/allocator got a turn each round -- unnecessary now that scheduler-sim-live-allocation gave sim mode the same real, capacity-checked picker/allocator threads normal mode uses. Narrowed reconciliation's trigger back to JOB_IS_RUN-only (undoing a 2026-09-11 widening whose own justification no longer holds), so a freshly-pushed job now always flows through the same live, verified decision path as normal mode. Reconciliation now only ever fires for a job already RUN from before the replay's own observation window -- the one case structurally invisible to the live picker. Also logged (bug-1837, not fixed here, needs its own design decision): sim_reconcile_unaccounted_jobs() calls a picker's on_dispatch() hook from the driver thread instead of the allocator thread plugin.h documents it belonging to -- currently inert since the only real picker plugin happens to lock internally, but not contract-safe for a future lock-free one. Fixing bug-1838 required re-examining every test exercising the old PEND-inclusive trigger; several needed their fixtures corrected to register a real worker (harmless before any capacity check existed), and others needed their actual intent re-derived and their assertions inverted or restated now that a PEND job is never eligible for reconciliation. Dated correction notes added in place to the scheduler-sim-eager-reconciliation spec, matching its own existing 2026-09-11 correction-note precedent. Verified: full scheduler suite 85/85, independently re-confirmed by running the four most affected binaries directly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
cd9ecb4159
commit
94115b0024
44 changed files with 2769 additions and 333 deletions
|
|
@ -231,6 +231,55 @@ int sched_account_jobs(xce_sched_core_t* core)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* bug-1836 (scheduler-driver-equivalence fix, Recorded-Decision
|
||||
* Reconciliation capacity gate): link-satisfying stubs, mirroring this
|
||||
* file's existing sched_account_jobs() no-op precedent immediately above --
|
||||
* sim_loop.c's sim_reconcile_unaccounted_jobs() now also calls
|
||||
* sched_check_host_satisfy()/sched_check_shared_satisfy() (resource.c) to
|
||||
* re-validate a recorded decision against live capacity, and
|
||||
* sched_charge_account() (resource.c) to keep that check's own view of
|
||||
* capacity up to date across multiple candidates in the same round. This
|
||||
* file never exercises real resource contention (same rationale as the
|
||||
* existing sched_account_jobs()/sched_ctx_get_uncomit_host() no-ops), so
|
||||
* the satisfy checks trivially always succeed and the charge call is a
|
||||
* no-op. */
|
||||
int sched_check_host_satisfy(xce_sched_core_t* core, xce_sched_worker_t* w,
|
||||
xvec_t* uncomitted, xvec_idval_t* wanted,
|
||||
xvec_idval_t* unmeet)
|
||||
{
|
||||
(void)core;
|
||||
(void)w;
|
||||
(void)uncomitted;
|
||||
(void)wanted;
|
||||
(void)unmeet;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sched_check_shared_satisfy(xce_sched_core_t* core, xvec_t* uncomitted,
|
||||
xvec_idval_t* wanted, xvec_idval_t* unmeet)
|
||||
{
|
||||
(void)core;
|
||||
(void)uncomitted;
|
||||
(void)wanted;
|
||||
(void)unmeet;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sched_charge_account(xce_sched_core_t* core, xce_job_account_t* acct)
|
||||
{
|
||||
(void)core;
|
||||
(void)acct;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sched_uncharge_account(xce_sched_core_t* core, xce_job_account_t* acct)
|
||||
{
|
||||
(void)core;
|
||||
(void)acct;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Real reimplementation of schedobj.c's sched_resolve_job_picker -- same
|
||||
* rationale/algorithm as test_sim_startup.c's/test_core_full_cycle.c's own
|
||||
* copies (schedobj.c is not linked: it would need plugin_register(), which
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue