myxce/src/controller
Rongsong Shen c4fd3e1c8f fix(ha-single-leader-role,ha-repl-hardening): promotion must register standbys with the WAL replicator
Live symptom: every write (jobsub) on a healthy 3-node cluster returned
E_XCE_NOT_READY (10013) — the primary had no write quorum and committed_lsn was
stuck at 0, even though both standbys were connected, heartbeating, streamed, and
the primary RECEIVED their WAL ACKs.

Root cause: raft_cb_become_leader registers a surviving vote endpoint with
repl_add_standby only when ectx->votes[i].peer != NULL, but raft_cb_send_vote_request
set votes[i].ep and never votes[i].peer. So at promotion the guard failed, the
standbys were added to ha->standby_endpoints (streaming) but NOT to the replicator
array c->persist.repl.standbys[] (commit/quorum). Consequently repl_on_ack could
not find the ack's ep (slot_idx=-1) -> commit_on_ack never ran -> committed_lsn
never advanced; majority_candidate/repl_active_standby_count saw 0 standbys ->
no write quorum -> the dispatch gate rejected every write with -XCE_ERR_NOT_READY.
(Streaming/persistence worked, which masked it: reslist/workerlist succeed, only
writes fail.)

Fix: raft_cb_send_vote_request now also sets ectx->votes[votes_idx].peer = peer
(the &candidates[peer_idx] pointer already computed for the connect) at the same
success site as .ep. peer points into the persistent myconf candidates[];
repl_add_standby copies host/port, so no lifetime dependency. Promotion now
registers each surviving vote ep -> standbys enter the replicator -> WAL ACKs
advance committed_lsn -> own-term gate opens -> write quorum established.

TDD: drive the real raft_cb_become_leader over a real persist/repl/commit fixture
and assert repl_active_standby_count post-promotion == N when votes[].peer is set,
== 0 when NULL (the bug). Full controller suite green under ASAN; election/commit/
repl/wire untouched apart from the one-line .peer assignment + a test seam.
2026-06-14 14:57:44 +00:00
..
include feat(ha-convergence-recovery): commit-gated scheduler egress — submit_lsn tagging + watermark gate (task 1.2) 2026-06-14 02:33:36 +00:00
testsuite fix(ha-single-leader-role,ha-repl-hardening): promotion must register standbys with the WAL replicator 2026-06-14 14:57:44 +00:00
apiserver.c add kiro skills 2026-05-21 03:41:57 +00:00
CLAUDE.md docs(ha-single-leader-role): sync steering + contributor docs to three-state model + own-term gate (task 6.1) 2026-06-13 14:58:55 +00:00
cluster.c fix(ha-config-bootstrap,ha-repl-hardening): config-less node must not win election 2026-06-14 08:58:08 +00:00
commit.c feat(ha-commit-engine): WAIT mode, admission cap, writable_lsn gate (task 2.2) 2026-06-11 15:24:30 +00:00
config_repl.c feat(ha-convergence-recovery): ACK-driven catch-up continuation + parity re-inclusion (task 4.2) 2026-06-14 05:45:20 +00:00
config_repl.h feat(ha-commit-barrier-rollout): config barrier with production ACK ingestion (task 5.2 + r1) 2026-06-13 03:46:29 +00:00
ctrl_metrics.c feat: P3-7 ctrl_metrics — 7 atomic counters/gauges + descriptor table + persist wiring 2026-05-08 00:04:06 +00:00
dataex.c fix(persist): zero nresvals_to_sched after free_name_val_list 2026-05-20 09:39:07 +00:00
egress.c feat(ha-convergence-recovery): commit-gated scheduler egress — submit_lsn tagging + watermark gate (task 1.2) 2026-06-14 02:33:36 +00:00
ha.c fix(ha-single-leader-role,ha-repl-hardening): promotion must register standbys with the WAL replicator 2026-06-14 14:57:44 +00:00
ha.h fix(ha-single-leader-role,ha-repl-hardening): promotion must register standbys with the WAL replicator 2026-06-14 14:57:44 +00:00
ha_convergence.c feat(ha-convergence-recovery): quorum transition logging — CAS edge-detect + 4 call sites (task 5.2) 2026-06-14 06:31:25 +00:00
job.c feat(ha-convergence-recovery): commit-gated scheduler egress — submit_lsn tagging + watermark gate (task 1.2) 2026-06-14 02:33:36 +00:00
join.c feat(ha-commit-barrier-rollout): config barrier with production ACK ingestion (task 5.2 + r1) 2026-06-13 03:46:29 +00:00
main.c feat(ha-convergence-recovery): self-restart primitive + demotion convergence (task 2.2) 2026-06-14 03:47:12 +00:00
meson.build fix(ha-commit-engine,persist): reserve WAL lsn 0 — first entry starts at lsn 1 2026-06-14 10:46:16 +00:00
misc.c save works 2026-03-05 16:03:37 +08:00
myapp.c fix(ha): election-safety hardening — vote gates, restored-vote term, freshness source 2026-06-10 01:25:39 +00:00
myconf.c feat(ha-config-bootstrap): implement --vcpus CLI, wire validation, remove vcpus from config (task 2.2) 2026-05-28 04:17:06 +00:00
opget.c fix(persist): zero nresvals_to_sched after free_name_val_list 2026-05-20 09:39:07 +00:00
opupd.c save works 2026-03-03 16:49:26 +08:00
persist.c fix(ha-wal-replication): standby durably persists replicated WAL before ACK 2026-06-14 13:10:02 +00:00
queue.c feat(ha-commit-barrier-rollout): commit-first-then-reply in all four handlers (task 3.2) 2026-06-12 10:28:25 +00:00
repl.c fix(ha-repl-hardening): snapshot fallback off-by-one — empty standby must stream, not snapshot 2026-06-14 12:10:40 +00:00
reply.c fix(persist): zero nresvals_to_sched after free_name_val_list 2026-05-20 09:39:07 +00:00
resources.c update controller code 2025-11-05 16:58:57 +08:00
sched.c feat(ha-convergence-recovery): commit-gated scheduler egress — submit_lsn tagging + watermark gate (task 1.2) 2026-06-14 02:33:36 +00:00
startup_validation.c feat(ha-heartbeat-liveness): add validate_heartbeat_config startup check (task 1.2) 2026-06-01 12:26:29 +00:00
task.c save works 2026-03-04 18:18:53 +08:00
worker.c feat(ha-commit-barrier-rollout): commit-first-then-reply in all four handlers (task 3.2) 2026-06-12 10:28:25 +00:00