feat(ha-term-safety): drive ACK path through raft_on_append_entries_reply + advance_commit (task 3.3)
Includes fix for bug-960: endpoint-type-aware peer-index resolution (promoted-vote relative vs heartbeat-standby absolute) with fail-loud bounds check, preventing an out-of-bounds match_index[] write / wrong-peer false-quorum on the replication ACK path.
This commit is contained in:
parent
754e586f8f
commit
f1783f7952
4 changed files with 466 additions and 2 deletions
|
|
@ -333,6 +333,47 @@ int ha_self_restart(cluster_t *c);
|
|||
int ha_primary_log_append(cluster_t *c, uint32_t type,
|
||||
const void *payload, uint32_t len, uint64_t *out_lsn);
|
||||
|
||||
/*
|
||||
* ha_raft_on_repl_ack (ha-term-safety task 3.3, R4.1/R4.5): drive the library on
|
||||
* a replication ACK. Routes a successful WalAck through raft_on_append_entries_reply
|
||||
* (updating the library's match_index[]/next_index[] at the absolute peer index)
|
||||
* then raft_advance_commit, so the library recomputes the current-term-gated
|
||||
* commit (the Figure-8 rule) and MAY fire on_commit_advanced — the task-2.4
|
||||
* callback that feeds the existing synchronous commit barrier. A current-term
|
||||
* quorum advances committed only when the agreed entry is current-term; a
|
||||
* prior-term agreed entry is held; a stale-term reply is dropped by the library.
|
||||
*
|
||||
* `abs_peer_idx` is the ABSOLUTE library peer index (j != self_idx), the same
|
||||
* index space as match_index[]/next_index[]. The CALLER resolves it per endpoint
|
||||
* type via ha_repl_ack_abs_peer_idx — promoted-vote eps carry a relative votes
|
||||
* index, heartbeat standby eps carry an already-absolute index. This seam must
|
||||
* NOT remap again. An out-of-range / self index is rejected loudly (returns
|
||||
* -EINVAL, no library accounting) so the library's unchecked match_index[] write
|
||||
* is never corrupted (no false quorum, no OOB). `acked_lsn` is the standby's
|
||||
* matched index (WalAckReply.lsn); `reply_term` is the reply's term.
|
||||
*
|
||||
* Leader-only effect: raft_advance_commit returns -EPERM off the leader (no
|
||||
* commit change, no callback) — harmless on a node that is no longer primary.
|
||||
* Non-blocking (ha-async-io): the library performs no I/O; on_commit_advanced
|
||||
* only records the barrier ceiling. Returns 0 on success; -EINVAL on a
|
||||
* no-cluster context or a rejected peer index. */
|
||||
int ha_raft_on_repl_ack(cluster_t *c, int abs_peer_idx, uint64_t acked_lsn,
|
||||
uint64_t reply_term);
|
||||
|
||||
/*
|
||||
* ha_repl_ack_abs_peer_idx (ha-term-safety task 3.3 remediation): resolve the
|
||||
* ABSOLUTE library peer index from an ACK endpoint's stored peer_idx, branching
|
||||
* on endpoint type (mirrors the standby_endpoints scan at ha.c:6187-6189):
|
||||
* - ep_is_vote != 0 (promoted vote ep, vote_ep_ctx_t): peer_idx is a
|
||||
* self-EXCLUDED votes index → remap abs = peer_idx < self_idx ? peer_idx
|
||||
* : peer_idx+1.
|
||||
* - ep_is_vote == 0 (heartbeat standby ep, standby_ep_ctx_t, ctx==NULL):
|
||||
* peer_idx is ALREADY absolute → pass through.
|
||||
* self_idx == ha->my_priority. Pure (no side effects); the single source of
|
||||
* truth shared by the production ACK call site and the unit test so the
|
||||
* remap-vs-passthrough distinction cannot drift. */
|
||||
int ha_repl_ack_abs_peer_idx(ha_state_t *ha, int ep_is_vote, int peer_idx);
|
||||
|
||||
/*
|
||||
* ha_schedule_demotion_convergence: schedule the one-shot delaymgr task that
|
||||
* truncates above committed_lsn (Req 1.2), WARN-logs the discarded range
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue