parjob-placement now covers full LSF-style parallel placement: task range (-n min,max), capacity-driven partitioning, span[ptile=n], span[hosts=1], span[block=n] and a host-count limit. bug-1931 points to it for the full task-range behaviour. pend-reason-push-dedup: skip pushing a job's pend reason to the controller when it equals the last one the controller accepted. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
25 lines
2.7 KiB
Markdown
25 lines
2.7 KiB
Markdown
# Requirements Document
|
|
|
|
## Project Description (Input)
|
|
**Who has the problem:** operators of an XCE cluster, through the load on the controller and its HA standbys. Every pend-reason push becomes a durable, Raft-replicated log entry.
|
|
|
|
**Current situation:** the scheduler publishes every PEND decision in every scheduling session. `xce_sched_driver_on_decision()` (`src/scheduler/src/driver.c:914-919`) wraps the decision and calls `sched_publish_pend_reason()` (`scheduler.c:1913`) without comparing it with what was pushed before. On the controller each push goes through `set_preason()` (`src/controller/job.c`) and `persist_job_hook_fun`'s `HOOK_DETAIL_SETPREASON` arm, which appends a pend-reason WAL record (`src/include/wal_types.h` ~235-265, bug-1692) that is replicated to the standbys. A job that stays pending for hours with the same reason therefore costs one network push plus one durable, replicated WAL write per session, multiplied by every pending job.
|
|
|
|
**What should change:** when a job's pend reason in the current session is identical to the one last successfully pushed for it (full structural match, libxce `job_preason_eq()`, `preason.h`), the scheduler skips the push. Only real changes reach the controller.
|
|
|
|
Questions to settle in requirements:
|
|
- **Baseline:** the last reason the controller *accepted* for the job, not merely the last one computed. A failed or retried push must not update it.
|
|
- **Losing the baseline:** after a scheduler restart or failover, or a controller failover or resync, the baseline starts empty, so every pending job is pushed once.
|
|
- **Controller-side clears:** `do_clr_preason()` (dispatch, requeue, other state changes) must invalidate the baseline so the next PEND is pushed even if it matches the old reason.
|
|
- **Memory:** cost per pending job — keep a deep copy (exact compare) or a hash (cheaper, tiny collision risk).
|
|
- **Where the baseline lives:** on the scheduler's job object, or in the driver.
|
|
- **Simulator and replay:** the decision stream, the decision trace and `--sim-verify` must still see every PEND decision; only the publish to the controller is skipped.
|
|
- **Observability:** count skipped pushes (log or stats).
|
|
- **Defense in depth (optional):** a controller-side guard that skips the WAL append when the incoming reason equals the stored one.
|
|
|
|
Related: bug-1932 (session-level unsatisfiable-request cache, which skips repeated computation within one session), bug-1927 (pend reasons recorded once per job), spec `libxce-alloc-preason-equality` (`job_preason_eq`).
|
|
|
|
Status: initialized only; requirements to be discussed with the user before `/kiro-spec-requirements`.
|
|
|
|
## Requirements
|
|
<!-- Will be generated in /kiro-spec-requirements phase -->
|