fix(controller): debounce RDHUP-triggered failover — stop the term-escalation storm (bug-1310, task 5.10b)
A dead primary's control fd RDHUPs faster than an election settles. The 5.6 guard only drops an RDHUP while the role is instantaneously CTRL_ELECTING/ prevote; an RDHUP landing in the gap after a lost election (role briefly back to CTRL_STANDBY) re-triggers a fresh ha_begin_failover -> PreVote -> real election (term++). One bump per RDHUP -> unbounded escalation under a sustained cadence (observed round 4: 48 begin_failovers, terms 6->24, round overran the harness window). Fix: ha_state_t.last_failover_ms (atomic) stamped at ha_begin_failover; ha_on_primary_ctrl_fd_rdhup drops an RDHUP within 2*election_timeout_ms of the last trigger (closes the dead fd, returns) so the election's own jittered retry (5.7) runs without the external RDHUP cadence adding term bumps. First trigger never debounced; genuine loss still fails over, at most once per window. Validation: unit-proven — test_rdhup_within_cooldown_is_debounced (recent last_failover -> stays CTRL_STANDBY) vs test_rdhup_single_node_reaches_primary (last_failover=0 -> CTRL_PRIMARY) is a differential proof. Soak: 10/10 elect, terms 4->14 bounded, begin_failover 14/14/12 (was 48), committed_job_loss=0, no regression. The stochastic storm did not recur this run (debounce fired 0x), so soak-reproduction of the storm is still pending; the mechanism rests on the unit test. Election suites green (rdhup 8/0, prevote 12/0, core_safety 24/0, election 28/0, failover_prevote 6/0). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JDYFbrgyDHbvNYcxApKhrX
This commit is contained in:
parent
cc80e65288
commit
0d70d5e412
5 changed files with 175 additions and 1 deletions
|
|
@ -160,6 +160,7 @@ typedef struct {
|
|||
/* watchdog_stop / watchdog_thread deleted — replaced by ha_arm_heartbeat_timeout_vtask */
|
||||
void *ssl_ctx; /* SSL_CTX* cast; avoids pulling openssl headers here */
|
||||
uint64_t jitter_seed; /* xorshift64 PRNG state for election jitter */
|
||||
_Atomic uint64_t last_failover_ms; /* CLOCK_MONOTONIC ms of last failover trigger; RDHUP debounce (5.10b) */
|
||||
zarray_t *standby_endpoints; /* connected standby controller endpoints for config push */
|
||||
/* ── New fields added by ha-config-bootstrap spec ──────── */
|
||||
uint64_t voted_for_term; /* Req 9: term of last granted vote */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue