feat(raft-apply-decoupling): split fact receipt to durable-append-only (task 4.1)
Convert on_job_start/on_job_finish/on_job_fail/on_job_postdone to validate and durably append only -- BEFORE_EVENT validation hook unchanged, AFTER_EVENT (post-mutation) hook no longer fires at receipt, live state mutation removed. Adds persist_submit_job_fact() (persist.c) since the durable append previously lived inside the very AFTER_EVENT hook this task silences; wire format is unchanged and identical to what apply_committed_entry() already routes. mark_job_start/mark_job_finish (single caller each) renamed in place to record_job_start_fact/record_job_finish_fact. mark_job_fail/ mark_job_update (shared with job_ctrl's client-command path, out of boundary) left untouched; new durable-append-only siblings record_job_fail_fact/record_job_update_fact added instead. Accepts a narrow, permanent regression: on_job_postdone's finish_time anomaly backstop has no wire-format equivalent and is dropped (affects only a rare no-prior-exit-status path). Two critical hazards discovered by review, documented in tasks.md, MUST be resolved before task 6 wires apply_committed_entry() into a live path: (1) persist_job_hook_fun still fires on HOOK_DETAIL_JOB_UPDATE and will double-append every live-applied fact; (2) record_job_fail_fact/ record_job_update_fact precompute a final state that can be silently clobbered by a concurrent intervening fact once apply is deferred by the commit round-trip.
This commit is contained in:
parent
f357215a6d
commit
23cbfb48e1
5 changed files with 492 additions and 116 deletions
|
|
@ -3931,6 +3931,27 @@ int persist_has_pending_apply(persist_t* p, uint64_t lsn)
|
|||
return found;
|
||||
}
|
||||
|
||||
/* raft-apply-decoupling task 4.1 (Req 5.1): the receipt-time durable-append
|
||||
* primitive for a worker-reported job-state fact. Unlike persist_job_hook_fun
|
||||
* below (an AFTER_EVENT hook that fires only once a mutation has already
|
||||
* happened), this is a direct, hook-fan-out-free call: job.c's fact receipt
|
||||
* handlers (record_job_start_fact/record_job_finish_fact/record_job_fail_fact/
|
||||
* record_job_update_fact) call this INSTEAD of mutating and firing
|
||||
* AFTER_EVENT, so no notification (scheduler dispatch, slot release,
|
||||
* apiserver push) can ever fire for an uncommitted fact (Req 5.3). `state`
|
||||
* is always WAL_MODE_RETAIN for every job-state fact type (verified against
|
||||
* wal_classify's table) — hardcoded here rather than routed through
|
||||
* wal_classify since none of these types are detail-disambiguated the way
|
||||
* WAL_WORKER_CTRL is. */
|
||||
int persist_submit_job_fact(persist_t* p, uint32_t wal_type, uint64_t jobid,
|
||||
int state)
|
||||
{
|
||||
wal_jobstate_t js = { .jobid = jobid, .state = (uint32_t)state };
|
||||
|
||||
return wal_hook_append_classified(p, wal_type, WAL_MODE_RETAIN, &js,
|
||||
sizeof(js));
|
||||
}
|
||||
|
||||
/* P0 payload: just the detail value (4 bytes).
|
||||
* Full Cap'n Proto serialization is wired in Task 15. */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue