Skip to content

fix(perps): connection-aware ensureReady() to fix stale cache on slow connections cp-7.67.0#26324

Merged
abretonc7s merged 7 commits intomainfrom
fix/perps/cache-issues-v2
Feb 20, 2026
Merged

fix(perps): connection-aware ensureReady() to fix stale cache on slow connections cp-7.67.0#26324
abretonc7s merged 7 commits intomainfrom
fix/perps/cache-issues-v2

Conversation

@abretonc7s
Copy link
Copy Markdown
Contributor

@abretonc7s abretonc7s commented Feb 20, 2026

Description

Fixes TAT-2597 and TAT-2598: After the preload PR merged, slow connections caused StreamChannels to exhaust 150 polling retries (30s) in ensureReady() and silently give up, leaving users with stale REST cache and no live WebSocket data — positions not appearing after trade, missing prices.

Root Cause: StreamChannel.ensureReady() used blind polling (isReady every 200ms × 150 retries) with no awareness of WebSocket connection state. On slow connections, the connection had not even established yet, so polling burned through all retries before data could arrive.

Fix:

  • PerpsConnectionManager.waitForConnection() — exposes init/reconnect promises so channels can await instead of blind-polling
  • StreamChannel.ensureReady() — detects isConnecting state and awaits the connection promise via awaitConnectionThenConnect()

Result: PriceStreamChannel retries dropped from 33 → 0 on device after this fix.

Changelog

CHANGELOG entry: Fixed stale cache on slow connections where positions and prices were not updating after a trade

Related issues

Fixes: TAT-2597, TAT-2598

Manual testing steps

Feature: Perps live data on slow connections

  Scenario: user opens a trade on a slow connection
    Given the app is connected to a slow 3G network
    And the user has navigated to the Perps trading screen

    When user opens a new position
    Then the position appears immediately in the positions list
    And price stream connects without excessive retries

  Scenario: user recovers from network drop
    Given the user is viewing live perps positions
    And the network connection drops momentarily

    When the network connection is restored
    Then live WebSocket data resumes without stale cache

Screenshots/Recordings

Before

After

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/stream reconnection timing and retry logic; mistakes could cause missed subscriptions or delayed real-time updates, though changes are localized and well-covered by tests.

Overview
Prevents Perps stream channels from burning through retry polling on slow connections by making StreamChannel.ensureReady() detect isConnecting and wait on the connection manager before retrying connect().

Adds PerpsConnectionManager.waitForConnection() (awaits init/reconnect promises, swallowing rejections) and introduces awaitConnectionThenConnect() with a sentinel timer to avoid duplicate awaits, plus a small deferConnect() timer cleanup fix and a shared PERPS_CONSTANTS.ConnectRetryDelayMs constant.

Expands unit tests to cover the new await/guard behavior (duplicate-await prevention, resolve/reject fallbacks) and updates market-data channel tests to use the new retry delay constant.

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

… connections

TAT-2597 / TAT-2598: After preload PR merged, slow connections caused
StreamChannels to exhaust 150 polling retries (30s) in ensureReady()
and silently give up, leaving users with stale REST cache and no live
WebSocket data — positions not appearing after trade, missing prices.

- Add PerpsConnectionManager.waitForConnection() exposing init/reconnect
  promises so channels can await instead of blind-polling
- StreamChannel.ensureReady() now detects isConnecting state and awaits
  the connection promise via awaitConnectionThenConnect()
- Add [PERPS_DEBUG] instrumentation across StreamManager, ConnectionManager,
  and usePerpsLivePositions for diagnosing data flow issues
- PriceStreamChannel: 33 retries → 0 on device after this fix
@abretonc7s abretonc7s requested a review from a team as a code owner February 20, 2026 05:27
@github-actions
Copy link
Copy Markdown
Contributor

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-perps Perps team label Feb 20, 2026
Strip ~150 lines of debug instrumentation added during TAT-2597/2598
investigation. Reverts all modified DevLogger calls to their original
wording and removes logs that duplicate existing error handling or
trace normal execution paths. The functional fix (connection-aware
ensureReady, awaitConnectionThenConnect, waitForConnection) is
unchanged.
@github-actions github-actions bot added size-S and removed size-M labels Feb 20, 2026
…guard

The deferConnect callback called connect() without clearing
deferConnectTimer first. If ensureReady() then entered the
isConnecting branch, awaitConnectionThenConnect() saw the stale
truthy timer ID and returned immediately — silently stopping retries.
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.

@abretonc7s abretonc7s changed the title fix(perps): connection-aware ensureReady() to fix stale cache on slow connections cp-7.67.0 fix(perps): connection-aware ensureReady() to fix stale cache on slow connections Feb 20, 2026
…layMs constant

Capture sentinel reference in awaitConnectionThenConnect so promise
handlers only null deferConnectTimer if it still matches, preventing
orphaned timer references on disconnect/resubscribe races.

Replace magic number 200 with PERPS_CONSTANTS.ConnectRetryDelayMs.
…ion, and isCurrentlyConnecting guard

Cover previously untested code paths to bump new-code test coverage:
- awaitConnectionThenConnect: early-exit, promise resolution, and rejection fallback
- MarketDataChannel: isCurrentlyConnecting deferred connect guard
- waitForConnection: initPromise and pendingReconnectPromise resolve/reject
@github-actions github-actions bot added size-M and removed size-S labels Feb 20, 2026
@abretonc7s abretonc7s changed the title cp-7.67.0 fix(perps): connection-aware ensureReady() to fix stale cache on slow connections fix(perps): connection-aware ensureReady() to fix stale cache on slow connections cp-7.67.0 Feb 20, 2026
@abretonc7s abretonc7s enabled auto-merge February 20, 2026 09:22
@github-actions
Copy link
Copy Markdown
Contributor

🔍 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 the Perps (perpetuals trading) feature, specifically improving the connection handling logic in PerpsStreamManager and PerpsConnectionManager. The key changes include:

  1. PerpsStreamManager.tsx: Replaced blind 200ms polling with a smarter approach that awaits the connection promise when the connection manager is actively connecting. Added awaitConnectionThenConnect() method.

  2. PerpsConnectionManager.ts: Added waitForConnection() method that returns a promise resolving when connection attempts complete.

  3. perpsConfig.ts: Added ConnectRetryDelayMs constant (200ms) for connection retry delay.

These changes affect the Perps WebSocket connection handling and could impact how the Perps feature initializes and reconnects. The PerpsStreamManager is imported by multiple Perps hooks (usePerpsLiveAccount, usePerpsLiveCandles, usePerpsLiveOrders, etc.) and views (PerpsTabView, TrendingView sections).

Per tag descriptions:

  • SmokePerps: Directly tests Perps functionality including Add Funds flow and balance verification
  • SmokeWalletPlatform: Perps is a section inside the Trending tab, and changes to Perps views affect Trending
  • SmokeConfirmations: Required because Perps Add Funds deposits are on-chain transactions

Performance Test Selection:
The changes modify the connection handling logic in PerpsStreamManager and PerpsConnectionManager, which could impact how quickly the Perps feature initializes and establishes WebSocket connections. The change from blind polling to promise-based awaiting could affect the time to load Perps market data and positions. @PerformancePreps covers perps market loading, position management, and add funds flow - all of which rely on the connection manager being properly initialized.

View GitHub Actions results

@sonarqubecloud
Copy link
Copy Markdown

@abretonc7s abretonc7s added this pull request to the merge queue Feb 20, 2026
Merged via the queue into main with commit 43cf1d8 Feb 20, 2026
97 checks passed
@abretonc7s abretonc7s deleted the fix/perps/cache-issues-v2 branch February 20, 2026 10:38
@github-actions github-actions bot locked and limited conversation to collaborators Feb 20, 2026
@metamaskbot metamaskbot added the release-7.68.0 Issue or pull request that will be included in release 7.68.0 label Feb 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants