feat(ha-term-safety): on_persist_entry callback body (task 2.1)

Replaces the iter-1 stub: persist_set_term(p, term) stamps the leader/library term
into hdr.term, then role-routes the write — primary via persist_wal_async, standby
via persist_wal_write_replicated(p, index, ...). Persist failure returns non-zero
(no false ACK; durable_lsn unchanged); bug-850 contiguity guard + persist-before-ACK
preserved beneath. In-flight raft_entry_blob_t {type,payload_len} envelope added to
wal_types.h (never enters the 40-byte header). 3 tests, reviewer APPROVED.

Deferred (recorded in tasks.md): task 3.1 must retire the hand-rolled primary append
so current_lsn tracks the library index; task 3.2 must not call on_persist_entry on
heartbeats. Per-group 0 failures (pre-existing test_commit_barrier_reply leak aside).
This commit is contained in:
Rongsong Shen 2026-06-22 04:53:18 +00:00
parent d540ebd183
commit 8f3d3ce8f4
5 changed files with 284 additions and 4 deletions

View file

@ -758,6 +758,21 @@ int handle_request_vote(ha_state_t *ha,
int in_catch_up_flag);
#endif
#ifdef XCE_TESTING
/*
* ha_cb_persist_entry_for_test (ha-term-safety task 2.1): invoke the WIRED
* on_persist_entry callback (s_real_cbs.on_persist_entry) directly so a unit
* test exercises the real adapter body — term stamping + WAL write at the given
* 1-based index == LSN — without driving raft_log_append (task 3.1). `ha` must
* have raft_c set to a cluster whose persist module is started. The `entry`
* blob is the adapter envelope (raft_entry_blob_t prefix + payload). Returns
* the callback rc (0 on durable persist; non-zero on persist failure, in which
* case nothing is ACKed). TEST-ONLY.
*/
int ha_cb_persist_entry_for_test(ha_state_t *ha, uint64_t index, uint64_t term,
const void *entry, size_t len);
#endif
/*
* ha_vote_self_freshness: compute the voter's effective freshness floor.
*