Skip to content

fix(gateway): freeze-frame an entity that is serving last known values - #565

Merged
mfaferek93 merged 3 commits into
mainfrom
fix/564-freeze-frame-while-disconnected
Jul 27, 2026
Merged

fix(gateway): freeze-frame an entity that is serving last known values#565
mfaferek93 merged 3 commits into
mainfrom
fix/564-freeze-frame-while-disconnected

Conversation

@mfaferek93

Copy link
Copy Markdown
Collaborator

Closes #564.

content_has_live_data() rejected any payload whose entity reported
connected: false, so a loss-of-comms fault - the one fault whose freeze frame
is the whole point, showing what the device held right before it went away -
could never have one. The guard was aimed at the row of nulls a cold cache
yields, but that case is already caught by values_have_data() one step later.

The gate now judges the payload: a non-empty items array captures, whatever the
link flag says. captured_at_ns continues to state when the frame was taken, so
nothing is presented as fresher than it is, and a bridge that serves per-value
staleness keeps saying so on its own route.

Tests: DisconnectedEntityWithLastKnownValuesIsCaptured (new, fails before),
ContentHasLiveData.GatesOnItemsNotOnTheLinkFlag, and the two "nothing usable ->
no frame" tests re-pointed at the case they were really guarding (down and
empty). Full gateway suite: 3793 tests, 0 failures, 448 skipped.

Copilot AI review requested due to automatic review settings July 26, 2026 17:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes entity freeze-frame capture for loss-of-communications scenarios in the gateway by allowing capture when an entity reports connected: false but still serves last-known values (i.e., non-empty items). This aligns freeze-frame behavior with the intended operational value of comms-loss faults: preserving the last observed state prior to disconnect, while still rejecting empty/all-null payloads.

Changes:

  • Update EntityFreezeFrameCapture::content_has_live_data() to gate on a non-empty items array rather than the connected flag.
  • Refine and expand unit tests to distinguish “disconnected with no usable values” (no frame) from “disconnected with last-known values” (frame captured).
  • Update API/docs comments in the header to reflect the new gating semantics and the continued reliance on values_have_data() to reject all-null rows.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/ros2_medkit_gateway/test/test_entity_freeze_frame_capture.cpp Adjusts existing tests and adds a new regression test to ensure disconnected entities with last-known values are captured.
src/ros2_medkit_gateway/src/entity_freeze_frame_capture.cpp Changes content_has_live_data() to evaluate payload content (non-empty items) instead of the link state flag.
src/ros2_medkit_gateway/include/ros2_medkit_gateway/entity_freeze_frame_capture.hpp Updates documentation of content_has_live_data() to reflect the new behavior and rationale.

@mfaferek93
mfaferek93 force-pushed the fix/564-freeze-frame-while-disconnected branch from b064d14 to 90c1f92 Compare July 26, 2026 19:33
@mfaferek93 mfaferek93 self-assigned this Jul 27, 2026

@bburda bburda left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things outside this diff that I think also need a change:

  • Would you add an integration test for the loss-of-comms case? The route test plugin hardcodes {"connected", true}, so no launch test can reach the new path today. test_entity_freeze_frame.test.py already loads that plugin, so a second entity returning {"connected": false, "items": [...]} would cover it.
  • Could you update the docs in this PR? docs/tutorials/snapshots.rst and docs/config/server.rst say the gateway snapshots the entity's "current data values" when the fault confirms, and docs/api/rest.rst calls freeze_frame "captured at fault confirmation". A frame may now hold values of unbounded age.

Comment thread src/ros2_medkit_gateway/src/entity_freeze_frame_capture.cpp
Comment thread src/ros2_medkit_gateway/src/entity_freeze_frame_capture.cpp
Comment thread src/ros2_medkit_gateway/src/entity_freeze_frame_capture.cpp
Comment thread src/ros2_medkit_gateway/test/test_entity_freeze_frame_capture.cpp Outdated
Comment thread src/ros2_medkit_gateway/test/test_entity_freeze_frame_capture.cpp Outdated
@mfaferek93

Copy link
Copy Markdown
Collaborator Author

Both outside-diff asks are in:

  • test_route_data_plugin gained a second, external app serving {"connected": false, "items": [last known values], "timestamp": ...}; the new launch case asserts its fault carries those values plus the x-medkit connected / source_timestamp markers - 844f195.
  • snapshots.rst, server.rst and rest.rst now say freeze-frame values may be last known when the entity is disconnected (age bounded only by the outage) and document the new x-medkit fields; captured_at is defined as dating the capture - daf5323.

A loss-of-comms fault could never carry a freeze frame: the capture rejected
any payload whose entity reported connected=false, which is exactly the fault
whose values matter. Judge the payload instead - a row of nulls is still
rejected one step later.
… frames

The content-based freeze-frame predicate also gated the fault-trigger value
fetcher, which kept threshold rules firing on frozen last-known values for a
whole outage; the fetcher now yields nullopt on connected=false. Frames carry
the payload's link flag and own timestamp into the snapshot's x-medkit block.
A frame for a disconnected entity holds the plugin's last known values,
aged by the outage; document that and the x-medkit connected and
source_timestamp snapshot fields.
@mfaferek93
mfaferek93 force-pushed the fix/564-freeze-frame-while-disconnected branch from daf5323 to 6a29bb0 Compare July 27, 2026 14:10
@mfaferek93
mfaferek93 merged commit 952384f into main Jul 27, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gateway: a comms-loss fault can never get a freeze frame

3 participants