docs(spec): application-profile: dispatch-window handling and profile content hash

- profile gone or changed between scheduler decision and controller
  dispatch: dispatch fails (retryable) and the job returns to PEND via
  requeue, never EXIT
- internal per-profile content hash (canonical capnp, excluding
  description) carried on the dispatch decision and the dispatch record

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-10-12 10:09:38 +00:00
parent 84f2068ae3
commit d88b9cb31f
Signed by untrusted user: rshen
GPG key ID: 80533536B0EB651C

View file

@ -365,7 +365,8 @@ restarted, and the scheduler no longer re-merges it.
`rusage[license=1]`) do not change when the profile changes, and are
rebuilt identically after a scheduler failover or restart;
- execution: mode, mode options, launch type, env, outer pre/post-exec,
limits.
limits;
- the profile content hash the record was built from.
- At each dispatch the controller puts the execution values into the job's
`start_info` for the worker, and the whole record into an additive
payload on the WAL dispatch fact
@ -399,6 +400,39 @@ with the reason "application profile X is not defined".
pending jobs or services, with counts; `xceadmin config upgrade` prints
it. Needs a new scheduler pend reason (profile missing from
`Conf4Sched`).
- **Between the scheduler's decision and the controller's dispatch**
(decided 2026-10-12, user). The scheduler merges with its copy of the
profile (`Conf4Sched`); the controller reads the profile again when it
builds the dispatch record. If the profile is gone or has changed in
between, the **dispatch fails and the job goes back to PEND through the
requeue path** (re-reading the profile, as any requeue does): gone → it
pends with "application profile X is not defined"; changed → the
scheduler re-merges with the new profile. Never EXIT.
- New dispatch failure site (e.g. `XCE_DISPATCH_FAIL_SITE_APP_PROFILE`),
classified retryable, unlike today's terminal
`XCE_DISPATCH_FAIL_SITE_QUEUE_EXEC` (`controller/job.c`). Nothing is
committed on this path (`j->job.allocs` is committed only after a
successful `xce_startjob_req()`). Requirements decide that it does not
count as a run or against requeue limits.
- A scheduler still on the old config may re-dispatch and be declined
again until the controller's config push reaches it; the existing
dispatch retry backoff bounds that.
- After the controller has built the record, profile changes no longer
matter: the worker starts from `start_info`.
- **Profile content hash** (decided 2026-10-12, user): an internal version
of each profile.
- Computed, never stored as state: one `src/lib` function hashes the
canonical Cap'n Proto encoding of the profile, excluding
`description`. Controller, scheduler and apiserver get the same value
from the same profile, also after failover or restart.
- The scheduler's dispatch decision carries the hash it merged with
(additive field); the controller compares it with the current
profile's hash at dispatch. A scheduler that sends no hash (rolling
upgrade) skips the check.
- The dispatch record stores it; "profile changed since dispatch" in job
details is a hash comparison; job details show it short
(`openfoam@3f2a9c`). Admins never set it.
- Base for the open "profile versioning and audit" item.
- Leaning, for requirements: `jobmod --app <new>` moves a pending job to
another profile (the owner, with `app:use` on the new one; admins in bulk,
e.g. `--app-from <old>`); the scheduler re-evaluates.