feat(ha-heartbeat-committed-propagation): standby OP_nop consume branch + term-guard (task 2.2)
Append a committed-consume branch to the OP_nop handler (existing liveness/reply byte-unchanged): ha_consume_heartbeat_committed applies the non-primary gate (3.4) + stale-term guard (accept hb->term >= ha->term, 3.2), then delegates to the monotonic ha_observe_heartbeat_committed (1.2). Absent body / zero / failed gate are no-ops (4.2). No vote-floor edit — safety is the term-guard. 4 tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8bfa861be2
commit
90e7179a89
5 changed files with 200 additions and 1 deletions
|
|
@ -4959,6 +4959,38 @@ void ha_observe_heartbeat_committed(cluster_t *c, uint64_t committed_lsn,
|
|||
committed_lsn, committed_config_tag, cur);
|
||||
}
|
||||
|
||||
/*
|
||||
* ha_consume_heartbeat_committed: standby OP_nop consume branch — the
|
||||
* non-primary gate (Req 3.4) + the stale-term guard (Req 3.2), then the
|
||||
* monotonic observe (Req 1.2). Reconcile-free; updates nothing on a NULL body,
|
||||
* a failed gate, or a zero committed value (Req 4.2). Pure additive helper —
|
||||
* the caller runs the unchanged liveness/reply path first (Req 4.1).
|
||||
*/
|
||||
void ha_consume_heartbeat_committed(cluster_t *c, const heartbeat_msg_t *hb)
|
||||
{
|
||||
if (!c || !hb)
|
||||
return;
|
||||
|
||||
/* (3.4) A primary uses its own authoritative committed — never an inbound
|
||||
* heartbeat value. Only non-primary nodes consume. */
|
||||
ctrl_role_t role =
|
||||
(ctrl_role_t)atomic_load_explicit(&c->ha.role, memory_order_acquire);
|
||||
if (role == CTRL_PRIMARY)
|
||||
return;
|
||||
|
||||
/* (3.2) Term-guard: a heartbeat from a primary whose term is behind ours is
|
||||
* stale/partitioned — reject its committed so it cannot inflate the
|
||||
* vote-freshness floor. Equal-or-newer term passes. */
|
||||
uint64_t myterm = atomic_load_explicit(&c->ha.term, memory_order_acquire);
|
||||
if (hb->term < myterm)
|
||||
return;
|
||||
|
||||
/* (1.2) Monotonic, reconcile-free learn. Zero/non-advancing LSN no-ops
|
||||
* inside the observe (Req 4.2). */
|
||||
ha_observe_heartbeat_committed(c, hb->committed_lsn,
|
||||
hb->committed_config_tag);
|
||||
}
|
||||
|
||||
void ha_disarm_heartbeat_timeout_vtask(ha_state_t *ha)
|
||||
{
|
||||
(void)ha;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue