Skip to content

Commit e5fd9a9

Browse files
committed
test(aggregation): prove a peer that comes back is taken back
Retention is well covered in one direction only. Every case that watches a peer go quiet leaves it quiet, so nothing observed the return trip, and the design doc's promise that a recovering peer is re-included rested on no test at all. A regression that kept replaying the retained copy would have poisoned the tree after a single outage with every suite still green. A peer is killed and then replaced through the same gate the trigger suite uses, so the return happens when the case asks for it rather than on a clock. The declared member's flag is watched down and back up, the runtime-discovered one disappears and is merged again, a read that answered not-responding answers with the peer's own payload, and the retained declaration does not linger beside the live copy. The two availability signals do not clear together, and the case pins that rather than papering over it: reachability clears on the first refresh after the health check passes, while is_online is the peer's own account of its graph and follows a refresh or two later.
1 parent 16adccd commit e5fd9a9

4 files changed

Lines changed: 975 additions & 1 deletion

File tree

docs/config/aggregation.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,15 @@ What clients see then depends on the peer's health check:
465465
incomplete refresh is logged at ``WARN``. Availability is untouched - the
466466
peer can still be reached; this gateway merely failed to read all of it.
467467

468+
A peer that starts answering again is read again on the next refresh, and a
469+
retained declaration is replayed only for a peer that could not be read - so
470+
the live answer replaces the retained one rather than being merged beside it.
471+
``x-medkit.available`` clears on that refresh, and the entities the peer only
472+
discovered at runtime, dropped while it was silent, are merged again with it.
473+
``x-medkit.is_online`` is the peer's own account of an App rather than a
474+
statement about the link, so after a gateway restart it stays ``false`` until
475+
that gateway has relinked its ROS graph.
476+
468477
Two statuses are read rather than treated as failures:
469478

470479
- ``404`` on a nested collection route means the peer runs a gateway version

src/ros2_medkit_gateway/design/aggregation.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,15 @@ GETs ``/api/v1/health`` on its peer. If the health check fails, the peer is
694694
marked unhealthy and excluded from fan-out queries and entity fetching.
695695

696696
When a peer recovers (health check succeeds again), it is automatically
697-
re-included.
697+
re-included: the next refresh fetches it like any other healthy peer, and since
698+
a retained declaration is replayed only for a peer that could not be read that
699+
cycle, the live answer replaces the retained one wholesale rather than being
700+
merged beside it. ``x-medkit.available`` therefore clears on that same refresh,
701+
and the entities the peer only discovered at runtime - dropped while it was
702+
silent - are merged again with it. ``x-medkit.is_online`` is read off the wire
703+
as the peer's own account of an App, not as a statement about the link, so an
704+
App on a gateway that has just restarted stays ``false`` for however many
705+
refreshes that gateway needs to relink its ROS graph, and then turns true.
698706

699707
``PeerClient::fetch_entities()`` reads a peer over several requests and either
700708
describes it whole or reports failure: a dead connection, a status a route has

src/ros2_medkit_integration_tests/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ if(BUILD_TESTING)
255255
# four where two are used takes two away from whatever the runner could
256256
# otherwise have started alongside it.
257257
set(_TWO_GATEWAY_TESTS
258+
test_peer_recovery
258259
test_triggers_restore_before_discovery)
259260
set(_TWO_GATEWAY_DOMAINS 2)
260261

@@ -297,6 +298,7 @@ if(BUILD_TESTING)
297298
test_graph_provider_greenwave 300
298299
test_graph_provider_stale 300
299300
test_graph_provider_sse 300
301+
test_peer_recovery 300
300302
test_triggers_restore_before_discovery 300)
301303
# Names actually matched against a discovered test_name in the two loops
302304
# below. Checked against _MEDKIT_TEST_TIMEOUT_OVERRIDES itself after both

0 commit comments

Comments
 (0)