feat(job-array-single-wal-record): wire array expansion into live apply
Adds case WAL_JOB_ARRAY_SUBMIT to apply_committed_entry() (the live apply pump / boot replay dispatch seam): calls restore_job_array() (task 3.1) instead of restore_job(), and on success fires HOOK_DETAIL_JOB_NEW exactly once carrying every newly created element in restore_job_array()'s own out_new_jobs list -- never once per element. No hook fires on an idempotent no-op (-EEXIST) or any genuine construction failure, honestly propagating task 3.1's documented bulk-insert-phase residual gap rather than papering over it. apply_wal_entry() (standby catch-up) is untouched -- task 3.3. Task 3.2 of job-array-single-wal-record.
This commit is contained in:
parent
7c755dc4d7
commit
0c4573b54a
3 changed files with 281 additions and 1 deletions
|
|
@ -2776,6 +2776,50 @@ int apply_committed_entry(persist_t* p, uint32_t wal_type, uint64_t lsn,
|
|||
return 1;
|
||||
}
|
||||
|
||||
case WAL_JOB_ARRAY_SUBMIT: {
|
||||
/* job-array-single-wal-record task 3.2 (design.md "Array Apply
|
||||
* Expansion"): the array-record analog of WAL_JOB_SUBMIT's
|
||||
* restore_job() above, dispatched from this SAME shared seam so live
|
||||
* apply, boot replay (both callers of this function), and (task
|
||||
* 3.3) standby catch-up can never diverge in how they expand a
|
||||
* committed array record (Req 3.1, 3.2).
|
||||
*
|
||||
* restore_job_array()'s return generalizes restore_job()'s
|
||||
* three-way contract to N elements: a positive count = the number
|
||||
* of genuinely NEW elements this call constructed (this is exactly,
|
||||
* and only, what the hook fire below carries — Req 3.4); -EEXIST =
|
||||
* every index in the record already existed (idempotent
|
||||
* whole-record no-op, Req 3.3) — no hook; a negative errno = a
|
||||
* genuine construction/resource-exhaustion failure (Req 9.4) — no
|
||||
* hook, propagated so persist_apply_pump_run() (task 4.1) can halt
|
||||
* and fence on it rather than silently skipping it. */
|
||||
xlist_t out_new_jobs;
|
||||
memset(&out_new_jobs, 0, sizeof(out_new_jobs));
|
||||
int rc = restore_job_array(c, payload, len, lsn, &out_new_jobs);
|
||||
if (rc == -EEXIST)
|
||||
return 0; /* idempotent re-apply (replay / resync) — no hook */
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Exactly ONE fire carrying every newly created element in one
|
||||
* list — never once per element (Req 3.4). out_new_jobs is already
|
||||
* the precise newly-created set restore_job_array() built; no
|
||||
* re-derivation via key_find needed. */
|
||||
t_apply_seam_notifying = true;
|
||||
xce_run_hooks(&c->hooksys, XCE_CONTROLLER_HOOK_JOB, HOOK_AFTER_EVENT,
|
||||
HOOK_DETAIL_JOB_NEW, c, &out_new_jobs);
|
||||
t_apply_seam_notifying = false;
|
||||
|
||||
/* Only the list's own backing array is released here — ownership of
|
||||
* every job_t* it holds already transferred to c->jobmgr inside
|
||||
* restore_job_array()'s bulk-insert pass, mirroring
|
||||
* test_job_array_apply.c's own xlist_fini(&out) usage after a
|
||||
* successful call. */
|
||||
xlist_fini(&out_new_jobs);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
case WAL_JOB_START:
|
||||
case WAL_JOB_FINISH:
|
||||
case WAL_JOB_STOP:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue