Skip to content

Conversation

@sanity
Copy link
Contributor

@sanity sanity commented Jan 25, 2026

Problem

When a user's PC suspends and resumes, River UI may miss contract updates that arrived while the page was hidden or the machine was suspended. The user would open River expecting to see recent messages but find stale state until they took an action (like sending a message) that triggered a state refresh.

Root cause: The PageBecameVisible handler (triggered by the browser's visibility change event) only called ProcessRooms which handles pending local changes but doesn't explicitly fetch the latest network state for all rooms.

User impact: After PC wake from suspension, users see outdated chat messages and miss recent activity.

Approach

Add a new RefreshAllRooms mechanism that explicitly fetches current state for all subscribed rooms after wake:

  1. New SynchronizerMessage::RefreshAllRooms - Message type to trigger refresh
  2. New RoomSynchronizer::refresh_all_rooms() - Sends GET requests for all known room contracts
  3. Modified PageBecameVisible handler - Now triggers RefreshAllRooms instead of just ProcessRooms

The GET requests fetch current contract state from the network, which is then merged with local state via the existing response handling, catching any updates missed during suspension.

Why this approach vs alternatives:

  • Could have modified ProcessRooms directly, but that would add overhead to every sync cycle
  • Could have tracked time-since-last-sync, but visibility change is the right trigger for suspension recovery
  • GET-based refresh is more reliable than relying on subscription pushes which may have been missed

Testing

  • Local verification: Checked with cargo check -p river-ui and cargo test -p river-core
  • No new automated tests added (would require mocking browser visibility API in WASM, which is complex)
  • Manual testing scenario: Open River, subscribe to room, suspend PC, have another user send message, resume PC, verify message appears

Additional Changes

Also fixes a pre-existing compilation error in example_data.rs where Configuration.name was accessed directly instead of through the new Configuration.display.name path introduced in a recent refactor.

[AI-assisted - Claude]

sanity and others added 2 commits January 25, 2026 10:27
…pdates

When a user's PC suspends and resumes, the River UI may miss contract
updates that arrived while the page was hidden. Previously, the
PageBecameVisible handler only triggered ProcessRooms which handles
pending changes but doesn't fetch the latest state from the network.

This adds a new RefreshAllRooms mechanism that:
1. Sends GET requests for all subscribed room contracts on wake
2. Fetches current network state to catch any missed updates
3. Merges the received state with local state

This fixes the issue where users would open River after PC suspension
and not see recent messages until they sent a new message.

Also fixes a pre-existing compilation error in example_data.rs where
Configuration.name was accessed directly instead of through the new
Configuration.display.name path.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The refresh_all_rooms() function sends GET requests to fetch current
state after wake from suspension, but GET responses were only being
processed for rooms in PENDING_INVITES. This fix adds handling for
GET responses for already-subscribed rooms by:

1. Adding fallback lookup in ROOMS when owner_vk not found in SYNC_INFO
2. Processing GET responses for existing rooms by merging retrieved
   state into current room state

This ensures updates missed during suspension are properly merged
when the UI wakes up and refreshes room state.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sanity sanity merged commit 4fb500d into main Jan 25, 2026
3 checks passed
@sanity sanity deleted the fix-suspension-recovery branch January 25, 2026 16:42
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.

2 participants