feat: wire ha_state_t into cluster_t + HA startup/shutdown lifecycle (P1-5)

This commit is contained in:
Rongsong Shen 2026-05-07 14:55:48 +00:00
parent 652b015458
commit c627f69d50
6 changed files with 241 additions and 13 deletions

View file

@ -9,6 +9,17 @@
#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.
*/
#include "xce/cluster_def.h"
#include "persist.h"
int ha_init(ha_state_t *ha, const ha_config_t *cfg, int my_priority)
{
if (!ha || !cfg)
@ -176,31 +187,57 @@ void ha_fini(ha_state_t *ha)
}
/*
* The three cluster_t-dependent stubs below cannot dereference c->ha until
* P1-5 adds `ha_state_t ha` to cluster_t. They compile as no-ops now and
* will be fleshed out in P1-3a after P1-5 wires the field in.
* 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).
*/
int am_i_primary(cluster_t *c)
{
(void)c;
/* P1-3 adds real election probing.
* Stub: always report not-primary until cluster wiring is in place. */
return 0;
return c->ha.my_priority == 0;
}
/*
* ha_promote_to_primary: increment term, set role=PRIMARY, then register
* persistence hooks (idempotency guard via hooks_registered).
* Safe to call on a zero-init cluster_t (zeroed hooksys → xce_add_hook
* returns -EINVAL harmlessly; hooks_registered is still set to 1).
*/
int ha_promote_to_primary(cluster_t *c)
{
(void)c;
/* Full sequence in P1-3a (WAL flush, hook calls, peer notify).
* Stub: no-op — role management moved to P1-3a. */
ha_do_promote(&c->ha);
/* Register persistence hooks — idempotency guard prevents double-add */
if (c->ha.hooks_registered == 0) {
xce_add_hook(&c->hooksys, XCE_CONTROLLER_HOOK_JOB,
(hook_fn_t)persist_job_hook_fun, &c->persist);
xce_add_hook(&c->hooksys, XCE_CONTROLLER_HOOK_QUEUE,
(hook_fn_t)persist_queue_hook_fun, &c->persist);
xce_add_hook(&c->hooksys, XCE_CONTROLLER_HOOK_WORKER,
(hook_fn_t)persist_worker_hook_fun, &c->persist);
c->ha.hooks_registered = 1;
}
return 0;
}
/*
* ha_demote_to_standby: disable persistence hooks, then set role=STANDBY
* and reset the hooks_registered idempotency guard (via ha_do_demote).
*/
int ha_demote_to_standby(cluster_t *c)
{
(void)c;
/* Full sequence in P1-3a.
* Stub: no-op — role management moved to P1-3a. */
/* Disable persistence hooks before changing role */
if (c->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_do_demote(&c->ha); /* sets role=STANDBY, resets hooks_registered=0 */
return 0;
}