forked from lei.chen/myxce
feat(raft-apply-decoupling): build apply_committed_entry single dispatch seam (task 2.2)
Add apply_committed_entry(persist_t*, wal_type, lsn, payload, len) in
persist.c/persist.h as the single seam that turns a committed WAL
entry into an in-memory mutation plus its post-mutation notification
hook, covering job submit, job-state facts, queue control, and
worker control. Job-state facts route through 2.1's guard-only
apply_job_update_transition() core and fire a generic
HOOK_DETAIL_JOB_UPDATE, not per-type hooks — the wire format
(wal_jobstate_t {jobid, state}) cannot supply what the type-specific
cores/hooks require. This is a real, documented deviation from
design.md's per-type dispatch wording; tasks.md's Implementation
Notes flags it as unresolved and blocking for whoever wires this
into a live path (4.1/6.2/6.3).
Not yet wired into any live call site (replay wiring is 2.3).
This commit is contained in:
parent
41d36204d5
commit
8c00f20cec
6 changed files with 689 additions and 1 deletions
|
|
@ -739,6 +739,58 @@ int persist_worker_hook_fun(int type, int situation, int detail,
|
|||
int apply_wal_entry(persist_t* p, uint32_t type, uint64_t lsn,
|
||||
const void* payload, uint32_t payload_len);
|
||||
|
||||
/* apply_committed_entry — raft-apply-decoupling task 2.2, design.md
|
||||
* "Apply Seam". The single dispatch function that mutates in-memory state
|
||||
* for ONE committed WAL entry, shared (once tasks 2.3/6.1 wire their call
|
||||
* sites) by restart replay and the live commit-advance apply pump. Routes:
|
||||
* WAL_JOB_SUBMIT -> restore_job() (existing
|
||||
* idempotent, jobid-addressable construction primitive; -EEXIST is a
|
||||
* no-op re-apply, not an error)
|
||||
* WAL_JOB_{START,FINISH,FAIL,STOP,RESUME,
|
||||
* UPDATE,RUSAGE,CKPT,PREASON} -> apply_job_update_transition()
|
||||
* (the guard-only core extracted in task 2.1)
|
||||
* WAL_QUEUE_CTRL -> restore_queue_state()
|
||||
* WAL_WORKER_CTRL -> worker_from_capnp()
|
||||
* and fires the entry type's AFTER_EVENT notification hook exactly once,
|
||||
* strictly after the mutation completes, and ONLY when a genuine (non-
|
||||
* duplicate, non-guard-rejected) mutation actually occurred.
|
||||
*
|
||||
* Deviation from a literal per-type hook fan-out: the on-disk fact payload
|
||||
* (wal_jobstate_t {jobid, state}) carries only the job's resulting state, not
|
||||
* the original job_pidinfo_t / xce_jobfinish_t / job_failinfo_t a type-
|
||||
* specific mark_job_* hook (HOOK_DETAIL_JOB_START/EXIT/FAIL) expects its
|
||||
* subscribers to dereference. The real risk is sched.c's sched_job_start_fun/
|
||||
* sched_job_exit_fun/sched_job_fail_fun, which dereference info->jobid
|
||||
* directly in a struct initializer — before even their `situation` switch,
|
||||
* with no NULL guard (apiserver.c's equivalent subscribers are NOT at risk:
|
||||
* they store the `info` pointer itself into the notify union (e.g.
|
||||
* `.data = { .pidinfo = info }`) inside `case HOOK_AFTER_EVENT:`, without
|
||||
* dereferencing any of its fields at this call site — unlike sched.c's
|
||||
* unconditional `info->jobid` access in a top-level struct initializer).
|
||||
* Every job-state fact type therefore routes through the
|
||||
* guard-only apply_job_update_transition() core and fires
|
||||
* HOOK_DETAIL_JOB_UPDATE, whose subscribers take only (cluster_t*, job_t*) —
|
||||
* matching what this wire format can actually supply without fabricating
|
||||
* data. No task in the current plan (2.3, 4.1, 4.2, 6.1, 6.2, 6.3) closes
|
||||
* this gap — task 4.1 is exclusively about removing state mutation/hook-
|
||||
* firing from worker-fact receipt-time handlers, not about enriching the
|
||||
* wire format. Closing it would require either a design.md correction
|
||||
* (formally accepting this HOOK_DETAIL_JOB_UPDATE substitution as final —
|
||||
* design.md's Apply Seam section and Fact Ingestion Event Contract
|
||||
* currently describe per-type hook dispatch this wire format cannot
|
||||
* support) or a new task to enrich the WAL wire format for job-state facts.
|
||||
*
|
||||
* NOT this function's concern (owned by whichever caller drives it — the
|
||||
* replay segment reader today, the live apply pump added by task 6.1):
|
||||
* advancing p->current_lsn, oversized-payload rejection, WAL_CHECKPOINT
|
||||
* skip. See apply_wal_entry's doc comment above for why those stay
|
||||
* physical-layer-owned.
|
||||
*
|
||||
* Returns 0 on success (including a no-op idempotent re-apply or a guard-
|
||||
* rejected/duplicate transition), negative on a genuine apply failure. */
|
||||
int apply_committed_entry(persist_t* p, uint32_t wal_type, uint64_t lsn,
|
||||
const void* payload, uint32_t len);
|
||||
|
||||
/* Load a snapshot file from path, set p->checkpoint_lsn and p->current_lsn.
|
||||
* lsn hint is informational — the actual LSN is read from the file header.
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue