feat(job-array-single-wal-record): wire array expansion into apply_wal_entry
Adds case WAL_JOB_ARRAY_SUBMIT to apply_wal_entry() (standby catch-up dispatch), calling restore_job_array() hook-free, matching the existing WAL_JOB_SUBMIT case's shape exactly. Review found apply_wal_entry() has zero production call sites -- a 2026-07-10 refactor (ha_standby_advance_committed_and_apply) moved standby entity materialization onto the same apply_committed_entry() pump the primary uses; the code comment claiming otherwise predated that refactor and was never updated. Requirement 3.1/3.2/4.1 are fully delivered by task 3.2 alone. This task's wiring is kept as defensive parity with WAL_JOB_SUBMIT's existing, equally-dead case in the same switch, not as an independent delivery path -- design.md and tasks.md corrected accordingly. Task 3.3 of job-array-single-wal-record.
This commit is contained in:
parent
0c4573b54a
commit
b0c7cfe548
4 changed files with 260 additions and 12 deletions
|
|
@ -67,10 +67,10 @@
|
|||
- _Requirements: 3.1, 3.4_
|
||||
- _Boundary: Array Apply Expansion_
|
||||
|
||||
- [ ] 3.3 Wire array expansion into standby catch-up
|
||||
- [x] 3.3 Wire array expansion into standby catch-up (defensive parity — see note below)
|
||||
- Call 3.1's same primitive from the separate standby catch-up/replicated-apply dispatch path for the new WAL record type, without firing any notification (matching that path's existing hook-free behavior for the single-job case)
|
||||
- Observable: a test applies the same committed array record through both the live-apply dispatch and the standby catch-up dispatch and confirms byte-identical resulting job state either way
|
||||
- _Requirements: 3.1, 3.2, 4.1_
|
||||
- _Requirements: 3.1, 3.2, 4.1 — delivered by task 3.2 alone (see Implementation Notes); this task is defensive parity, not an independent delivery path_
|
||||
- _Boundary: Array Apply Expansion_
|
||||
|
||||
- [ ] 3.4 Unit tests for array expansion
|
||||
|
|
@ -173,4 +173,5 @@
|
|||
- **Task 1.3**: `meson test --suite xce`'s `libxce test` target SIGABRTs under ASAN leak detection whenever any code path exercises a `job_init()` failure — root cause is the vendored `rtti` library's `makeInstance()` not freeing its allocation when a type's `.init()` returns negative (no `.c` source available, headers-only in the nix store). This is pre-existing and independently reproduced against an unmodified pre-task `jobj.c`, not introduced by this feature. It will fire again on any future task whose tests exercise a `create_job()`/`makeJob()` failure path (e.g. task 3.1/3.4's fault-injection tests for `restore_job_array()`) — expect the same SIGABRT-not-assertion-failure signature (`grep ":FAIL"` on the Unity log will be empty; the failure is LeakSanitizer-only) and do not treat it as a new regression without the same stash-and-reproduce check task 1.3's review used.
|
||||
- **Task 1.3**: `job_obj_init()`/`job_obj_fini()` are now idempotent (atomic_flag-guarded) — safe to call more than once without an intervening `fini()`. Any future test construction can rely on this instead of coordinating a single call site.
|
||||
- **Task 1.3**: `makeJobsub()`/`makeJobstartinfo()` now return `-ENODEV` (not a generic `-EINVAL`) when the interning table isn't initialized — if a later task's error handling branches on `job_init()`'s return value, `-ENODEV` is a distinct, checkable signal for "table not ready" vs. other construction failures.
|
||||
- **Task 3.3**: `apply_wal_entry()` (persist.c:2574) is dead code in production — confirmed via exhaustive grep (zero call sites outside its own declaration/definition/comments) and via `ha.c:8024`'s `ha_standby_advance_committed_and_apply` (dated 2026-07-10), whose own doc comment explicitly says standby entity materialization now goes through the SAME `apply_committed_entry()`/`persist_apply_pump_kick` pump the primary uses, not `apply_wal_entry()`. The persist.c:3722 comment claiming otherwise predates that refactor and was never updated (design.md corrected accordingly). Requirement 3.1/3.2/4.1 are fully delivered by task 3.2 alone. Task 3.3's code was kept (not discarded) as defensive parity with `WAL_JOB_SUBMIT`'s existing, also-dead case in the same switch — it is tested and correct, just not currently reachable in production. If `apply_wal_entry()` is ever revived or removed entirely in a future spec, this task's case should move or be deleted with it.
|
||||
- **Task 3.1**: `restore_job_array()`'s atomicity has one narrow, documented exception (design.md updated to match): the final bulk-insert-into-`c->jobmgr` pass can itself fail on allocation/growth exhaustion (`c->jobmgr` grows via `realloc()`; no capacity-reservation primitive exists anywhere in `kv.c`/`kvmgr.c`/`zarray.c` to pre-check this before mutating). On this specific failure, the function never silently claims success — it returns a negative errno — but an already-inserted prefix `[0, inserted)` can be left genuinely, permanently visible in `c->jobmgr` (no `key_del` exists to undo it), and that prefix is NEVER included in `out_new_jobs`, so `HOOK_DETAIL_JOB_NEW` never fires for it, not on this attempt or any later successful retry of the same LSN. **Tasks 3.2/4.x must account for this**: those elements are individually addressable (status/cancel/completion work normally) but permanently un-pushed to the scheduler/API server unless something later re-derives and re-notifies them — this is a real gap in the current design, not yet solved, and task 4.x's Live Apply Resource Fence design should explicitly decide whether/how to handle it (e.g. detecting this residual state and re-notifying on self-heal) rather than only handling the construction-phase failure case.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue