refactor: simplify ha.c comments and extract HA config constants

- Add HA_DEFAULT_* constants to ha.h; use them in cluster_init()
- Strip stale task-label comments (P1-3a, P1-5, P1-6, P3-6 refs)
- Remove self-documenting 'Step N:' annotations from ha_do_promote/demote
- Rewrite stale forward-reference notes as current WHY comments
- Remove resolved TODO P0-8b from cluster.c
This commit is contained in:
Rongsong Shen 2026-05-08 03:56:38 +00:00
parent da6d967a33
commit d61f91b99c
3 changed files with 29 additions and 50 deletions

View file

@ -9,14 +9,8 @@
#include <stdlib.h>
#include <string.h>
/*
* P1-5: include full cluster_t definition (with embedded ha_state_t ha)
* and persist hook function declarations so ha_promote_to_primary /
* ha_demote_to_standby can dereference c->ha and manage persist hooks.
*
* Circular-include safety: cluster_def.h includes ha.h (which has include
* guards), and ha.h only forward-declares cluster_t — no cycle.
*/
/* Circular-include safety: cluster_def.h includes ha.h (include-guarded),
* and ha.h only forward-declares cluster_t — no cycle. */
#include "xce/cluster_def.h"
#include "persist.h"
@ -49,14 +43,10 @@ int ha_init(ha_state_t *ha, const ha_config_t *cfg, int my_priority)
return 0;
}
/* ── P1-3a: promotion / demotion / SIGUSR1 ─────────────────── */
/* ── Promotion / demotion / SIGUSR1 ────────────────────────── */
/*
* Async-signal-safe: the handler only performs an atomic store on an
* int-width type, which is async-signal-safe on all POSIX platforms
* (POSIX.1-2017 §2.4.3). The pointer is set once by ha_install_sigusr1()
* before signals are enabled; no locking is required.
*/
/* Async-signal-safe: atomic store on int-width type (POSIX.1-2017 §2.4.3).
* Pointer set once before signals are enabled — no locking required. */
static ha_state_t *g_sigusr1_ha = NULL;
static void sigusr1_handler(int sig)
@ -80,29 +70,19 @@ void ha_install_sigusr1(ha_state_t *ha)
void ha_do_promote(ha_state_t *ha)
{
/* Step 1: Increment election term — monotonically increasing fencing token */
/* Monotonically increasing fencing token — standbys reject entries from lower terms */
atomic_fetch_add_explicit(&ha->term, 1, memory_order_acq_rel);
/* Step 2: Set role to PRIMARY */
atomic_store_explicit(&ha->role, (int32_t)CTRL_PRIMARY, memory_order_release);
/* Step 3: Reset last_received_crc chain (COH-5 — new primary starts fresh chain) */
/* COH-5: new primary starts a fresh CRC chain; standbys reset their chain on catch-up */
ha->last_received_crc = WAL_CRC_NONE;
/* Steps 4+: hook re-registration, standby heartbeat, cluster_start() —
* deferred to ha_promote_to_primary(cluster_t*) in P1-5. */
}
void ha_do_demote(ha_state_t *ha)
{
/* Step 1: Set role to STANDBY — vcpu threads will reject new primary ops */
atomic_store_explicit(&ha->role, (int32_t)CTRL_STANDBY, memory_order_release);
/* Step 2: Reset hook idempotency guard — next promote will re-register */
/* Reset so the next ha_promote_to_primary() re-registers hooks idempotently */
ha->hooks_registered = 0;
/* Step 3: hook disable done in ha_demote_to_standby(cluster_t*) in P1-5
* because it needs the cluster's hooksys_t. */
/* Hook disable requires hooksys_t — done by ha_demote_to_standby(cluster_t*) */
}
/* ── P3-6: Test-only failover shim ────────────────────────────── */
@ -140,8 +120,7 @@ void ha_check_heartbeat_nocluster(ha_state_t *ha)
(uint64_t)(now.tv_nsec - last.tv_nsec) / 1000000ULL;
if (elapsed_ms >= ha->config.heartbeat_timeout_ms) {
/* Primary appears dead — full promotion in P1-3a.
* For now: set failover_requested so watchdog thread can act. */
/* Primary appears dead — set failover_requested; watchdog acts on it */
atomic_store_explicit(&ha->failover_requested, 1, memory_order_release);
}
}
@ -163,10 +142,11 @@ static void *ha_watchdog_thread(void *arg)
ha_check_heartbeat_nocluster(ha);
/* Handle manual failover request (SIGUSR1 path — P1-3a) */
if (atomic_load_explicit(&ha->failover_requested, memory_order_acquire)) {
atomic_store_explicit(&ha->failover_requested, 0, memory_order_release);
/* Full ha_promote_to_primary(c) call in P1-3a when cluster_t is available */
/* Promotion requires cluster_t; the watchdog only has ha_state_t.
* Full ha_promote_to_primary(c) is called from the cluster's own
* failover path which holds cluster_t context. */
}
}
return NULL;
@ -197,7 +177,7 @@ void ha_fini(ha_state_t *ha)
pthread_mutex_destroy(&ha->lock);
}
/* ── P1-6: Redirect helpers ────────────────────────────────── */
/* ── Redirect helpers used by join.c ───────────────────────── */
/*
* ha_should_redirect: returns 1 when this standby knows the primary's
@ -229,15 +209,7 @@ int ha_no_primary_known(const ha_state_t *ha)
return (ha->primary_host[0] == '\0' || ha->primary_port == 0) ? 1 : 0;
}
/*
* P1-5: cluster_t now embeds ha_state_t ha, so the three functions below
* can dereference c->ha.
*/
/*
* am_i_primary: priority-0 node is primary for single-node P1.
* Full election probing added in P1-3 (future).
*/
/* priority-0 node is primary; full election probing is a future enhancement */
int am_i_primary(cluster_t *c)
{
return c->ha.my_priority == 0;