feat(ha-term-safety): on_commit_advanced barrier trigger + commit-gate ownership (task 2.4)

This commit is contained in:
Rongsong Shen 2026-06-22 07:33:04 +00:00
parent 2c5d298cb5
commit 3470bdfb71
6 changed files with 363 additions and 9 deletions

View file

@ -50,7 +50,7 @@
- _Requirements: 1.3, 3.1_
- _Depends: 1.1_
- [ ] 2.4 Implement `on_commit_advanced` as a trigger into the existing barrier, and resolve the commit-gate ownership
- [x] 2.4 Implement `on_commit_advanced` as a trigger into the existing barrier, and resolve the commit-gate ownership
- Feed the library-supplied `commit_index` into the existing synchronous commit barrier (`commit_advance_locked`/`commit_set_writable_lsn`) as the commit SOURCE; the barrier mechanism (majority self-cap at durable floor, persist-before-ACK) is unchanged
- Resolve double-gating (REVIEW ISSUE 3): state and implement whether the controller's existing own-term `WAL_NOOP` writable gate is now redundant with the library's current-term commit rule (and removed) or retained as a complementary durability gate; ensure the two cannot deadlock (commit held by both) or leave a gap
- Observable completion: a strict library commit advance releases the barrier's WAIT only on durable majority; the term-blind safe-commit is no longer the commit source; a unit test pins the own-term-gate decision
@ -159,3 +159,8 @@
- **2.3 done.** on_send_append_entries → repl_send_append_entries: builds a WalCatchupEntry AE to standbys[peer_idx].ep carrying prev_log_index/prev_log_term; for n_entries==1 sources the entry at prev_log_index+1 from the local WAL (term via persist_entry_term, type+payload via ha_read_wal_entry_at); heartbeat = n_entries==0 (zero entries). Async (xce_wal_batch_req_raw), payload freed on all paths. 2 tests via repl_send_ae_capture_hook seam. Reviewer APPROVED.
- **DEFERRED to task 3.2:** leader_commit is accepted+captured but NOT yet wire-encoded — WalCatchupEntry needs a `leaderCommit` capnp field + standby intake of it (3.2). Comment at repl.c corrected to state this.
- **LOW (future refactor):** ha_read_wal_entry_at duplicates WAL segment-file parsing already in persist.c/config_repl.c/waldump.c — a persist_read_entry_at() accessor would consolidate; correct as written.
- **2.4 done.** on_commit_advanced (ha.c `ha_cb_commit_advanced_stub` body, still named `*_stub` per the 2.1–2.3 convention) routes the library `commit_index` into the barrier via NEW `commit_set_raft_commit_index(ce, commit_index)` (commit.c) → `ce->raft_commit_index` ceiling. `majority_candidate_locked` now caps `committed = min(durable-majority, raft_commit_index)` on BOTH the standalone (n_peers<=1) and multi-peer paths. Own-term WAL_NOOP writable gate **RETAINED** (design 193/201/228) — proven non-conflicting: `writable_lsn` is only a WAIT predicate (`wait_done_locked`), `raft_commit_index` only caps `committed_lsn` — disjoint quantities, no deadlock; `committed=min(...)` ⇒ no gap; ceiling only ever lowers `cap` (starts at durable floor) ⇒ never over-commits; `assert(cand<=persist_durable_lsn)` still holds. Monotonic: setter raises only on `commit_index > raft_commit_index`. 5 tests; reviewer APPROVED (stash-and-rebuild baseline proved test_repl_unit 6-fail + 1 timeout are pre-existing bug-924/working-dir env, not regressions).
- **FEATURE GATE (critical for 3.x):** ceiling is INERT while `raft_commit_index == 0` (no on_commit_advanced fired). Lowest real LSN is 1 (commit_submit rejects lsn==0), so `0` unambiguously means "nothing committed" — no 0-vs-unset window. Tasks 3.1–3.3 wiring `raft_advance_commit` on the ACK path will fire the FIRST `on_commit_advanced(commit_index>=1)` and engage the library source; until then the autonomous barrier is preserved (no steady-state regression, R5.4).
- **DEFERRED to 3.x (decommission the term-blind source):** `ha_compute_safe_committed_lsn` is no longer the commit source but is NOT yet removed — it still drives the promotion-time safe truncate (R5). 3.x must ensure no path still feeds it INTO the barrier as a commit source once `raft_advance_commit` is wired.
- For-test seam: `ha_cb_commit_advanced_for_test` (ha.h, XCE_TESTING) + `commit_set_raft_commit_index` are the hooks 5.1 integration tests should reuse.