feat(raft-apply-decoupling): point restart replay at apply_committed_entry seam (task 2.3)
Rewire replay_wal()'s per-entry apply call from apply_wal_entry() to apply_committed_entry() (task 2.2's shared dispatch seam), so restart replay and the future live commit-advance pump (task 6.1) both produce materialized state deterministically from the committed log. apply_wal_entry() is not retired -- it remains ha.c's live standby catch-up/replicated-apply dispatch, untouched. Documents a real hazard: replay now fires AFTER_EVENT hooks for the full post-checkpoint WAL range on every restart, including entries already applied+notified in a prior process life. Traced and confirmed inert today for both hook consumers (scheduler registers post-boot, apiserver gates notify on a connected endpoint empty at boot); flagged in tasks.md and in-line at the call site for re-verification before tasks 4.1/6.1/6.2/6.3 make this path broadly live.
This commit is contained in:
parent
8c00f20cec
commit
50d016d905
5 changed files with 434 additions and 5 deletions
|
|
@ -2961,10 +2961,34 @@ static int replay_wal(persist_t* p, uint64_t from_lsn,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Logical entity restore. The CRC chain + current_lsn are owned by
|
||||
* this replay loop (current_lsn advanced below; last_crc at line
|
||||
* ~1601), not by apply_wal_entry. */
|
||||
apply_wal_entry(p, hdr.type, hdr.lsn, payload, hdr.payload_len);
|
||||
/* Logical entity restore via the shared apply seam
|
||||
* (raft-apply-decoupling task 2.3, design.md "Apply Seam"): the
|
||||
* SAME apply_committed_entry() dispatch the live commit-advance
|
||||
* apply pump will use (task 6.1), so a node's materialized state
|
||||
* is the deterministic result of its committed log regardless of
|
||||
* whether it got there via restart replay or live apply
|
||||
* (Req 3.1-3.4). apply_wal_entry() (this replay loop's previous
|
||||
* per-entry dispatch) is NOT retired by this change — it remains
|
||||
* the live standby catch-up/replicated-apply dispatch used
|
||||
* elsewhere (ha.c); it is simply no longer this loop's call. The
|
||||
* CRC chain + current_lsn remain owned by this replay loop
|
||||
* (current_lsn advanced below; last_crc at line ~1601) — neither
|
||||
* dispatch function ever touched them (bug-778).
|
||||
*
|
||||
* KNOWN HAZARD (tracked in tasks.md Implementation Notes, task
|
||||
* 2.3): this replays the FULL post-checkpoint WAL range on every
|
||||
* restart (last_applied_lsn is not persisted, deliberately
|
||||
* recomputed here), so apply_committed_entry()'s AFTER_EVENT
|
||||
* hooks fire again for entries already applied+notified in a
|
||||
* prior process life. Confirmed inert today: scheduler hooks
|
||||
* aren't registered until a post-boot network JOIN
|
||||
* (on_scheduler_join, sched.c), and apiserver hooks — though
|
||||
* registered before this runs — gate their notify on a
|
||||
* connected endpoint that is empty at first-boot replay time.
|
||||
* MUST be re-verified before tasks 4.1/6.1/6.2/6.3 make this
|
||||
* path broadly live. */
|
||||
apply_committed_entry(p, hdr.type, hdr.lsn, payload,
|
||||
hdr.payload_len);
|
||||
free(payload);
|
||||
|
||||
/* Advance current_lsn to one past this entry */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue