fix(ha-bootstrap): priority staggering and candidate_id in election

Two Raft correctness fixes:

1. Priority staggering in ha_wait_for_heartbeat_or_timeout():
   Add my_priority × election_priority_step_ms to the timeout so
   ctrl-a (priority=0) times out first and starts election before
   ctrl-b (priority=1) and ctrl-c (priority=2). This gives the
   highest-priority node a head start and prevents simultaneous
   campaigning that causes perpetual split votes.

2. candidate_id in vote RPC:
   Pass the actual node name (myconf->name) as candidate_id instead
   of "". This fixes the voted_for deduplication gate (Req 2.6):
   a peer that already voted for ctrl-a will correctly deny a
   second vote request from ctrl-b in the same term.

   Thread context gets my_name field; am_i_primary_quorum() takes
   my_name parameter; all call sites updated (myapp.c, ha.c RDHUP,
   test_ha_election.c stubs).
This commit is contained in:
Rongsong Shen 2026-05-30 02:48:59 +00:00
parent fcfb82f7c7
commit 80950ffbba
4 changed files with 20 additions and 9 deletions

View file

@ -108,7 +108,8 @@ ctrl_role_t ha_elect_evaluate_and_signal(ha_state_t *ha, ha_elect_ctx_t *ctx);
ctrl_role_t am_i_primary_quorum(ha_state_t *ha, int n_peers,
xce_candidate_t **peers,
uint64_t my_config_tag, uint64_t my_lsn);
uint64_t my_config_tag, uint64_t my_lsn,
const char *my_name);
void handle_request_vote_reply(ha_state_t *ha, ha_elect_ctx_t *ctx,
int peer_idx, uint64_t term,
@ -531,7 +532,8 @@ static void test_single_node_self_elects_as_primary(void)
1, /* n_peers = 1 (single node) */
NULL, /* no other peers */
500ULL, /* my_config_tag */
100ULL /* my_lsn */);
100ULL, /* my_lsn */
"test-node");
TEST_ASSERT_EQUAL_INT(CTRL_PRIMARY, (int)role);
@ -613,7 +615,7 @@ static void test_split_vote_full_retry_increments_term(void)
/* Single-node: am_i_primary_quorum must self-elect and bump the term.
* (Multi-node split-vote path is verified in integration tests.) */
ctrl_role_t role = am_i_primary_quorum(&ha, 1, NULL, 100ULL, 50ULL);
ctrl_role_t role = am_i_primary_quorum(&ha, 1, NULL, 100ULL, 50ULL, "test-node");
TEST_ASSERT_EQUAL_INT(CTRL_PRIMARY, (int)role);
TEST_ASSERT_GREATER_THAN_UINT64(initial_term,