feat(controller-status): carry election time on the heartbeat (task 7.3)

The primary echoes its own last_known_elected_at_ms on every outgoing
heartbeat (threaded through xce_ha_heartbeat_req's existing scalar-arg
plumbing, alongside term/committed_lsn/committed_config_tag); a standby
processing a received heartbeat (ha_consume_heartbeat_committed, the sole
production call site) stores it unconditionally into its own
last_known_elected_at_ms, reconcile-free -- no other HA field moves.
ha_observe_heartbeat_committed itself is untouched; the new store sits
next to its call site, not inside it.

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 06:03:03 +00:00
parent 21ae00b375
commit 30adc52ea3
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
9 changed files with 252 additions and 33 deletions

View file

@ -1347,18 +1347,20 @@ int xce_nop_req(endpoint_t* ep)
}
/* xce_ha_heartbeat_req: send the HA heartbeat as an OP_nop request carrying a
* HeartbeatMsg body with the primary's committed position. Clone of the nop
* send path plus a heartbeatmsg body. Non-blocking, no reply awaited (the
* standby's StateReport rides the normal nop reply). senderPriority is unused
* (0). Generic xce_nop_req stays body-less. */
* HeartbeatMsg body with the primary's committed position and its own
* election time (Req 12.2). Clone of the nop send path plus a heartbeatmsg
* body. Non-blocking, no reply awaited (the standby's StateReport rides the
* normal nop reply). senderPriority is unused (0). Generic xce_nop_req stays
* body-less. */
int xce_ha_heartbeat_req(endpoint_t* ep, uint64_t term, uint64_t committed_lsn,
uint64_t committed_config_tag)
uint64_t committed_config_tag, uint64_t elected_at_ms)
{
heartbeat_msg_t hb = {
.sender_priority = 0,
.term = term,
.committed_lsn = committed_lsn,
.committed_config_tag = committed_config_tag,
.elected_at_ms = elected_at_ms,
};
/* clang-format off */
xce_request_t request = {