feat(controller-status): add election-time schema fields + ha_state_t (task 7.1)

Adds CtrlStatus.electedAtMs@14 and HeartbeatMsg.electedAtMs@4 to the
capnp schema, their hand-authored typemap.h counterparts, and a new
ha_state_t.last_known_elected_at_ms field alongside last_known_committed_lsn.
Schema/state plumbing only -- nothing stamps or consumes these fields yet
(tasks 7.2-7.5). Codec round-trip tests confirm both new fields survive
encode/decode unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RLSNJhNoULvVcUhXEFafQC
This commit is contained in:
Rongsong Shen 2026-09-16 04:21:02 +00:00
parent 7556856e5c
commit cae1039ed7
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
6 changed files with 184 additions and 1 deletions

View file

@ -229,6 +229,44 @@ static void test_ha_init_zeroes_standby_convergence_fields(void)
printf("test_ha_init_zeroes_standby_convergence_fields: PASS\n");
}
/* ── Task 7.1 (controller-status delta, Req 12.1): ha_state_t.last_known_elected_at_ms
* zero-initialised by ha_init ──────────────────────────────────────────────
*
* New HA state (design.md "Design Delta — Requirement 12", Locked Decision 2)
* holding the currently-known primary's election time, declared alongside
* last_known_committed_lsn/last_known_committed_config_tag. Stamped by
* promotion (task 7.2, not yet wired) and learned via heartbeat (task 7.3,
* not yet wired); this test only proves the field starts at the well-defined
* zero/unknown value before any election, matching its siblings.
*/
static void test_ha_init_zeroes_last_known_elected_at_ms(void)
{
ha_state_t ha;
ha_config_t cfg = {
.heartbeat_interval_ms = 3000,
.heartbeat_timeout_ms = 10000,
.election_timeout_ms = 2000,
.probe_connect_timeout_ms = 500,
.max_promotion_retries = 5,
};
TEST_ASSERT_EQUAL_INT(0, ha_init(&ha, &cfg, 0));
TEST_ASSERT_EQUAL_UINT64(
0, atomic_load_explicit(&ha.last_known_elected_at_ms,
memory_order_acquire));
/* field must be writable (mirrors the sibling last_known_* fields) */
atomic_store_explicit(&ha.last_known_elected_at_ms,
UINT64_C(1781939830911), memory_order_release);
TEST_ASSERT_EQUAL_UINT64(
UINT64_C(1781939830911),
atomic_load_explicit(&ha.last_known_elected_at_ms,
memory_order_acquire));
ha_fini(&ha);
printf("test_ha_init_zeroes_last_known_elected_at_ms: PASS\n");
}
/* ── Task 3.1: ha_process_standby_state convergence tracking ─────────────── */
/*
@ -991,6 +1029,7 @@ void test_ha_role(void)
RUN_TEST(test_ha_init_zeroes_new_fields);
/* Task 1.4: ha-repl-hardening per-standby convergence fields */
RUN_TEST(test_ha_init_zeroes_standby_convergence_fields);
RUN_TEST(test_ha_init_zeroes_last_known_elected_at_ms);
/* Task 3.1: ha_process_standby_state convergence tracking */
RUN_TEST(test_process_standby_state_converged);
RUN_TEST(test_process_standby_state_lsn_behind);