feat(ha-heartbeat-liveness): idle-triggered primary NOP per standby (task 2.2)

Extend primary_heartbeat_fn to read last_push_time per standby and send NOP
only when elapsed >= heartbeat_interval_s. on_standby_connected writes
last_push_time before ctrlhello send. Remove workaround xce_nop_req at end
of on_standby_connected. Add ha_nop_req_hook XCE_TESTING seam. 3 new tests.
This commit is contained in:
Rongsong Shen 2026-06-01 15:05:41 +00:00
parent 738859fb4e
commit 622302a55c
3 changed files with 298 additions and 18 deletions

View file

@ -29,7 +29,7 @@
- _Requirements: 1.2, 1.4, 1.5, 1.6, 2.1, 2.2, 2.3, 4.2, 4.3, 5.2, 5.3, 5.4, 5.6_
- _Boundary: ha.c (standby liveness path)_
- [ ] 2.2 (P) Extend primary_heartbeat_fn with per-standby idle tracking
- [x] 2.2 (P) Extend primary_heartbeat_fn with per-standby idle tracking
- In `primary_heartbeat_fn`: for each ep in `ha->standby_endpoints`, cast `ep->data` to `standby_ep_ctx_t` and read `sctx->last_push_time`
- Compute `elapsed = now - sctx->last_push_time`; if `elapsed >= heartbeat_interval_ms` call `xce_nop_req(ep)` and write `sctx->last_push_time = now`; else skip NOP for this standby
- In `on_standby_connected`: write `sctx->last_push_time = clock_gettime(...)` immediately after TLS handshake completes (before ctrlhello send); this counts the ctrlhello as the first push
@ -70,7 +70,7 @@
- _Boundary: ha.c unit tests, startup_validation.c unit tests_
- _Depends: 2.1, 1.2_
- [ ] 4.2 (P) Unit tests for primary idle NOP suppression
- [x] 4.2 (P) Unit tests for primary idle NOP suppression
- Test `primary_heartbeat_fn`: sends NOP to standby when `last_push_time` elapsed ≥ `heartbeat_interval_ms`
- Test `primary_heartbeat_fn`: skips NOP when `last_push_time` elapsed < `heartbeat_interval_ms`
- Test `on_standby_connected` writes non-zero `last_push_time` immediately