feat(ha-convergence-recovery): self-restart primitive + demotion convergence (task 2.2)
This commit is contained in:
parent
c8e55947c2
commit
09103a3141
7 changed files with 337 additions and 43 deletions
|
|
@ -662,11 +662,53 @@ static void raft_cb_become_follower(void *ctx, uint64_t term, int leader_idx)
|
|||
}
|
||||
}
|
||||
|
||||
/* ha-convergence-recovery Req 1.1-1.3, 1.5: demotion convergence.
|
||||
*
|
||||
* Read the PRIOR role BEFORE the CTRL_STANDBY store below. If this node was
|
||||
* the PRIMARY, it may hold an uncommitted, potentially divergent WAL suffix
|
||||
* and provisional in-memory state. Synchronously disable the three
|
||||
* persistence hooks HERE (before any further event can be persisted — Req
|
||||
* 1.1, reusing ha_demote_to_standby's disable sequence), then schedule a
|
||||
* one-shot delaymgr task that truncates above committed_lsn and self-restarts
|
||||
* (Req 1.2/1.3/1.5) off this callback thread (D1: no file I/O or exec on the
|
||||
* iomgr/raft callback thread).
|
||||
*
|
||||
* Non-PRIMARY demotions (STANDBY/INIT/ELECTING) take the unchanged path —
|
||||
* they have no registered hooks and no provisional suffix to discard, so
|
||||
* their behavior is byte-equivalent to before this spec. */
|
||||
ctrl_role_t prior_role = (ctrl_role_t)atomic_load_explicit(
|
||||
&ha->role, memory_order_acquire);
|
||||
|
||||
if (prior_role == CTRL_PRIMARY && c != NULL) {
|
||||
/* Req 1.1: disable persistence hooks SYNCHRONOUSLY, before the role
|
||||
* store and before scheduling, so no provisional entry can be produced
|
||||
* after the higher term was observed. Mirrors ha_demote_to_standby
|
||||
* (ha.c) — disable each hook, then clear the idempotency guard. */
|
||||
if (ha->hooks_registered) {
|
||||
xce_disable_hook(&c->hooksys, XCE_CONTROLLER_HOOK_JOB,
|
||||
(hook_fn_t)persist_job_hook_fun);
|
||||
xce_disable_hook(&c->hooksys, XCE_CONTROLLER_HOOK_QUEUE,
|
||||
(hook_fn_t)persist_queue_hook_fun);
|
||||
xce_disable_hook(&c->hooksys, XCE_CONTROLLER_HOOK_WORKER,
|
||||
(hook_fn_t)persist_worker_hook_fun);
|
||||
ha->hooks_registered = 0;
|
||||
}
|
||||
}
|
||||
|
||||
atomic_store_explicit(&ha->role, (int32_t)CTRL_STANDBY,
|
||||
memory_order_release);
|
||||
INFO("HA FSM (raft): → CTRL_STANDBY (term=%" PRIu64 ", first_boot=%d)",
|
||||
term, is_first_boot);
|
||||
|
||||
/* Req 1.2/1.3/1.5: schedule the deferred truncate-above-committed-LSN +
|
||||
* self-restart now that hooks are disabled and the role is STANDBY. Only
|
||||
* the was-PRIMARY edge converges; all other edges skip this entirely. */
|
||||
if (prior_role == CTRL_PRIMARY && c != NULL) {
|
||||
WARN("HA: PRIMARY demoted (term=%" PRIu64 ") — scheduling demotion "
|
||||
"convergence (truncate above committed_lsn + self-restart)", term);
|
||||
(void)ha_schedule_demotion_convergence(c);
|
||||
}
|
||||
|
||||
/* Arm heartbeat watchdog — fires ha_on_primary_ctrl_fd_rdhup if primary
|
||||
* sends no ctrlhello within election_timeout_ms. */
|
||||
ha_arm_heartbeat_timeout_vtask(ha, c);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue