feat(ha-config-bootstrap): complete quorum election with mutex safety (task 4.3)

- am_i_primary_quorum(): per-peer pthreads, connect_ssl_raw + OP_requestVote
- pthread_mutex_t lock on ha_elect_ctx_t guards votes_granted/n_replied/max_resp
- done_posted guard in ha_elect_evaluate_and_signal prevents double sem_post
- Replace am_i_primary() with am_i_primary_quorum() in myapp.c
- Delete ha_check_priority_stepdown and ha_check_heartbeat_nocluster
- INFO logs: election outcome (Req 10.1), FSM transitions (Req 10.5)
- 24 election tests + 24 startup tests, 0 failures
This commit is contained in:
Rongsong Shen 2026-05-28 08:28:35 +00:00
parent 0f88d5d32a
commit 0c9c720b03
4 changed files with 390 additions and 98 deletions

View file

@ -99,7 +99,7 @@ Dependency order: startup validation (D) unblocks vtaskmgr before election (A);
- _Requirements: 2.2, 2.3, 2.4, 2.5, 2.6, 9.1_
- _Boundary: Controller FSM (ha.c)_
- [ ] 4.3 Implement ha_elect_evaluate_and_signal() and am_i_primary_quorum()
- [x] 4.3 Implement ha_elect_evaluate_and_signal() and am_i_primary_quorum()
- `ha_elect_evaluate_and_signal()`: count votes_granted; check freshness gate (any responding peer has higher config_tag or equal tag + higher LSN → yield); if `votes_granted >= quorum && !fresher_peer` → `CTRL_PRIMARY`; else → `CTRL_STANDBY`
- `am_i_primary_quorum()`: single-node shortcircuit (n_peers==1 → `CTRL_PRIMARY`); allocate `ha_elect_ctx_t`; spawn per-peer pthreads that call `connect_ssl_raw()` + send `OP_requestVote`; `sem_wait(&ctx->done)` for result; handle split-vote: one retry with incremented term + `xorshift64_jitter()` delay; second split → `CTRL_STANDBY`
- Replace `am_i_primary()` call in `myapp.c` with `am_i_primary_quorum()`