feat(ha-heartbeat-committed-propagation): add xce_ha_heartbeat_req sender (task 1.2)

Send the HA heartbeat as OP_nop + the existing HeartbeatMsg body carrying
{term, committed_lsn, committed_config_tag} (senderPriority unused). Generic
xce_nop_req untouched; C-side body support pre-existed (no typemap edit). Req 1.1
producer half. Round-trip test proves the 3 fields survive the wire; lib suite
0 failures under ASAN.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-06-20 11:40:31 +00:00
parent f4327ce4f6
commit 282a82ff7e
4 changed files with 129 additions and 1 deletions

View file

@ -1138,6 +1138,37 @@ int xce_nop_req(endpoint_t* ep)
return xce_request(ep, &request);
}
/* 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. */
int xce_ha_heartbeat_req(endpoint_t* ep, uint64_t term, uint64_t committed_lsn,
uint64_t committed_config_tag)
{
heartbeat_msg_t hb = {
.sender_priority = 0,
.term = term,
.committed_lsn = committed_lsn,
.committed_config_tag = committed_config_tag,
};
/* clang-format off */
xce_request_t request = {
.opcode = OPCode_nop,
.body_which = Request_body_heartbeatmsg,
.body = {
.heartbeatmsg = &hb
}
};
/* clang-format on */
if (ep == NULL) {
return -EINVAL;
}
return xce_request(ep, &request);
}
int xce_hello_req(endpoint_t* ep, char* msg)
{
/* clang-format off */