Skip to content

fix(perps): recover connection after app state changes cp-7.67.1#26780

Merged
aganglada merged 3 commits intomainfrom
fix/recovering-background
Mar 2, 2026
Merged

fix(perps): recover connection after app state changes cp-7.67.1#26780
aganglada merged 3 commits intomainfrom
fix/recovering-background

Conversation

@aganglada
Copy link
Copy Markdown
Contributor

@aganglada aganglada commented Mar 2, 2026

Description

Fixes Perps WebSocket connectivity issues when:

  1. App returns from background — after a few minutes in background, the OS silently kills the WebSocket but PerpsConnectionManager still reports isConnected = true. No code path detected the stale connection or triggered reconnection.
  2. WiFi/network drops and restores — toggling WiFi, airplane mode, or losing cellular signal kills the WebSocket, but since the app stays in active state, the existing AppState-based recovery (if any) never fires.

Root Cause

PerpsConnectionManager had no lifecycle awareness of:

  • React Native AppState transitions (background → foreground)
  • Network connectivity changes (offline → online via @react-native-community/netinfo)

Arthur's prior fix (#26334) made StreamChannel.ensureReady() connection-aware to avoid blind polling on slow connections, but it only helps when a reconnection is already in progress (isConnecting = true). After background resume or WiFi restore, nobody triggers the reconnection in the first place.

Fix

  • AppState listener — on active, cancels any pending grace period and runs validateAndReconnect()
  • NetInfo listener — tracks wasOffline state; on offline → online transition, runs validateAndReconnect()
  • validateAndReconnect(context) — shared method that sends a lightweight ping() health check to the active provider. If the ping fails (stale WebSocket), marks the connection as lost and triggers reconnectWithNewContext({ force: true }) which reinitializes the controller, validates with a fresh health check, and preloads all stream subscriptions.
  • Cleanup — both listeners are properly removed in cleanupStateMonitoring()

Changelog

CHANGELOG entry: Fixed Perps WebSocket not reconnecting after app resume from background or WiFi/network toggle

Related issues

Fixes: connectivity loss after backgrounding app, WiFi off/on not recovering Perps data

Manual testing steps

Feature: Perps connection recovery

  Scenario: App returns from background after several minutes
    Given the user has navigated to the Perps trading screen
    And the user has an open position

    When the user backgrounds the app for 3+ minutes
    And the user returns to the app
    Then the Perps WebSocket reconnects automatically
    And positions, prices, and account data resume updating

  Scenario: WiFi is toggled off and back on
    Given the user is viewing live Perps positions
    And WiFi is connected

    When the user turns WiFi off
    And waits a few seconds
    And turns WiFi back on
    Then the Perps WebSocket reconnects after network is restored
    And live data resumes without requiring navigation away

  Scenario: Airplane mode is toggled
    Given the user is on the Perps trading screen

    When the user enables airplane mode
    And then disables airplane mode
    Then the connection recovers and live data resumes

Screenshots/Recordings

Before

After backgrounding or WiFi toggle, Perps shows stale data with no automatic recovery. User must navigate away and back to restore the connection.

After

Connection automatically recovers via health-check ping and force reconnection. Live data resumes within seconds.

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Medium Risk
Touches Perps connection lifecycle and reconnection paths; regressions could cause reconnect loops or delayed/stuck loading during flaky connectivity.

Overview
Improves Perps WebSocket resilience by adding AppState and NetInfo listeners in PerpsConnectionManager to detect background→foreground and offline→online transitions, validate the connection via provider ping(), and force a reconnect when stale.

Adds network-restore retry/backoff knobs (NetworkRestoreMaxRetries, NetworkRestoreRetryBaseMs) and ensures cleanup of new subscriptions/timers on teardown; reconnection now explicitly calls PerpsController.disconnect() before init() to avoid skipping re-init on a dead socket.

Updates usePerpsHomeData to treat WebSocket-backed sections (positions/orders/activity) as loading while isConnecting, preventing brief empty-state flashes during reconnection.

Written by Cursor Bugbot for commit b3aab14. This will update automatically on new commits. Configure here.

@aganglada aganglada self-assigned this Mar 2, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 2, 2026

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-social-ai Social & AI team label Mar 2, 2026
@aganglada aganglada added team-perps Perps team and removed team-social-ai Social & AI team labels Mar 2, 2026
@github-actions github-actions bot added the size-M label Mar 2, 2026
@aganglada aganglada marked this pull request as ready for review March 2, 2026 14:50
@aganglada aganglada requested a review from a team as a code owner March 2, 2026 14:50
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 2, 2026

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokePerps, SmokeWalletPlatform, SmokeConfirmations
  • Selected Performance tags: @PerformancePreps
  • Risk Level: medium
  • AI Confidence: 85%
click to see 🤖 AI reasoning details

E2E Test Selection:
The changes are focused on improving the Perps (perpetuals trading) WebSocket connection resilience:

  1. usePerpsHomeData.ts: Added isConnecting state to loading indicators so the UI shows skeletons during reconnection instead of briefly flashing "no positions" → positions. This is a UX improvement for the Perps home data display.

  2. PerpsConnectionManager.ts: Major enhancement to handle connection recovery:

    • Added AppState listener to reconnect when app returns from background
    • Added NetInfo listener to reconnect when network connectivity is restored (WiFi on/off, airplane mode)
    • Added validateAndReconnect() method with ping health check
    • Added exponential backoff retry logic for network restore scenarios
    • Modified reconnectWithNewContext() to disconnect first before reinitializing to properly reset controller state
  3. perpsConfig.ts: Added two new constants for network restore retry configuration (max 8 retries, 1.5s base delay).

Tag selection rationale:

  • SmokePerps: Directly tests Perps functionality including Add Funds flow, balance verification, and Perps interface - all of which depend on the WebSocket connection being managed by PerpsConnectionManager
  • SmokeWalletPlatform: Per tag description, Perps is a section inside the Trending tab, so changes to Perps views affect Trending
  • SmokeConfirmations: Per tag description, when selecting SmokePerps, also select SmokeConfirmations because Add Funds deposits are on-chain transactions

The changes are isolated to the Perps feature and don't affect other wallet functionality like accounts, networks, swaps, or identity features.

Performance Test Selection:
The changes to PerpsConnectionManager affect WebSocket connection lifecycle, reconnection logic, and loading state management. These changes could impact the performance of Perps market loading, position management, and the overall responsiveness of the Perps interface during connection/reconnection scenarios. The @PerformancePreps tag covers perps market loading, position management, add funds flow, and order execution - all of which are affected by the connection manager changes.

View GitHub Actions results

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

}

await this.validateAndReconnect('appResume');
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale retry timer forces unnecessary reconnection on healthy connection

Medium Severity

handleAppStateChange does not call cancelNetworkRestoreRetry(), so pending retry timers from the network-restore path survive an app-resume reconnection. When such a timer fires after the connection was already restored, attemptNetworkRestoreReconnect calls validateAndReconnect with skipPing = true, which bypasses the health check that would detect the healthy connection. This forces an unnecessary disconnect-and-reconnect cycle, briefly disrupting live data streams that were just recovered.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I wonder if this is going to cause unecessary reconnections

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think the fix for this is calling this.cancelNetworkRestoreRetry() before await this.validateAndReconnect('appResume');

Draft PR here: #26803

I'm keeping it approved as is. The PR functionally fixes the reported bug for the incident. This could be seen as a follow up if you feel it's necessary

@aganglada aganglada changed the title fix(perps): recover connection after app state changes fix(perps): recover connection after app state changes cp-7.67.1 Mar 2, 2026
@aganglada aganglada added this pull request to the merge queue Mar 2, 2026
Merged via the queue into main with commit c4f83e4 Mar 2, 2026
113 checks passed
@aganglada aganglada deleted the fix/recovering-background branch March 2, 2026 17:34
@github-actions github-actions bot locked and limited conversation to collaborators Mar 2, 2026
@metamaskbot metamaskbot added the release-7.69.0 Issue or pull request that will be included in release 7.69.0 label Mar 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.69.0 Issue or pull request that will be included in release 7.69.0 size-M team-perps Perps team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants