fix(perps): prevent rate limit exhaustion during rapid market switching cp-7.72.0#28176
Conversation
…ng (#28141) - Add race guards in .then() handlers for activeAssetCtx, bbo, assetCtxs, and dexAllMids subscriptions to detect and clean up stale promises that resolve after cleanup - Add AbortController to cancel in-flight candleSnapshot REST calls on navigation away - Debounce CandleStreamChannel connections (500ms) to prevent WS subscription churn during rapid switching - Reduce initial candle fetch from YearToDate (500) to OneWeek (~168), with OneDay (~24) for cached revisits — full history lazy-loads on scroll - Add PERFORMANCE_CONFIG.CandleConnectDebounceMs constant
|
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. |
…mask-mobile-28141
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #28176 +/- ##
==========================================
+ Coverage 82.55% 82.64% +0.08%
==========================================
Files 4864 4866 +2
Lines 125683 126034 +351
Branches 28150 28254 +104
==========================================
+ Hits 103761 104163 +402
+ Misses 14747 14662 -85
- Partials 7175 7209 +34 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Automated Review — PR #28176
SummaryThis PR addresses HyperLiquid rate limit exhaustion (1200 weight/min) during rapid market switching through four targeted fixes: debounced candle WebSocket connections, lighter initial candle fetches (OneWeek/OneDay vs YearToDate), abortable REST calls via AbortController, and race guards on async subscription promises. The fix is well-structured, addresses the root causes, and achieves its stated goal. Full review detailsPrior ReviewsNo prior CHANGES_REQUESTED reviews. Only COMMENTED reviews from cursor (bot summary) and abretonc7s. Acceptance Criteria Validation
Code Quality
Fix Quality
Live Validation
Correctness
Static Analysis
Architecture & Domain
Risk Assessment
Recommended Action[APPROVE]
Line comments (3 comments: 1 suggestion, 2 nitpick)
No video evidence recorded. |
app/components/UI/Perps/providers/channels/CandleStreamChannel.ts
Outdated
Show resolved
Hide resolved
Automated Review — PR #28176
SummaryThis PR addresses HyperLiquid rate limit exhaustion (1200 weight/min) during rapid market switching through four targeted fixes: debounced candle WebSocket connections, lighter initial candle fetches (OneWeek/OneDay vs YearToDate), abortable REST calls via AbortController, and race guards on async subscription promises. The fix is well-structured, addresses the root causes, and achieves its stated goal. Full review detailsPrior ReviewsNo prior CHANGES_REQUESTED reviews. Only COMMENTED reviews from cursor (bot summary) and abretonc7s. Acceptance Criteria Validation
Code Quality
Fix Quality
Live Validation
Correctness
Static Analysis
Architecture & Domain
Risk Assessment
Recommended Action[APPROVE]
Line comments (3 comments: 1 suggestion, 2 nitpick)
No video evidence recorded. |
app/controllers/perps/services/HyperLiquidSubscriptionService.ts
Outdated
Show resolved
Hide resolved
app/components/UI/Perps/providers/channels/CandleStreamChannel.ts
Outdated
Show resolved
Hide resolved
app/controllers/perps/services/HyperLiquidSubscriptionService.ts
Outdated
Show resolved
Hide resolved
- Replace hardcoded 200ms with PERPS_CONSTANTS.ConnectRetryDelayMs - Add stale-promise race guard in activeAsset and bbo subscription handlers - Remove `as Promise<void>` casts by widening map type to `void | undefined`
Cover stale-promise race condition and activeAssetCtx error path in HyperLiquidSubscriptionService, raising new code coverage to 84%.
Nope, nothing visible really. |
There was a problem hiding this comment.
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.
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection:
SmokePerps is the primary tag as these changes directly affect perps trading functionality (candle chart data, market data subscriptions, order book subscriptions). Per SmokePerps tag description, SmokeWalletPlatform (Trending section) and SmokeConfirmations (Add Funds on-chain transactions) must also be selected. No other feature areas are impacted - no shared components, navigation, Engine, or other controllers were modified. Performance Test Selection: |
|
✅ E2E Fixture Validation — Schema is up to date |
|




Description
Fixes HyperLiquid rate limit exhaustion (1200 weight/min) during rapid market switching. Three root causes:
activeAssetCtx,bbo,assetCtxs, anddexAllMidssubscription promises that resolved after cleanup created orphan subscriptions. Fixed with race guards in.then()handlers that check if a newer subscription already exists.candleSnapshotREST calls (~22 weight each) continued in-flight after navigation. Fixed withAbortControllerinsubscribeToCandles.PERFORMANCE_CONFIG.CandleConnectDebounceMs) so rapid switches cancel the timer before the subscription fires.Changelog
CHANGELOG entry: Fixed rate limit errors when quickly switching between markets in the Perps trading view
Related issues
Fixes: #28141
Manual testing steps
Screenshots/Recordings
Before
429 errors after 3-4 market switches, chart subscription failures, leaked WebSocket subscriptions accumulating.
After
8 market switches with zero 429 errors (recipe: 28/28 pass). Stale subscriptions cleaned up automatically.
Validation Recipe (8 rapid market switches)
{ "title": "Validate rate limit fix - rapid market switching (#28141)", "initial_conditions": { "testnet": false }, "validate": { "runtime": { "steps": [ { "id": "nav_perps", "action": "navigate", "target": "PerpsTrendingView" }, { "id": "wait_list", "action": "wait_for", "test_id": "perps-market-row-item-BTC", "timeout": 10000 }, { "id": "open_btc", "action": "press", "test_id": "perps-market-row-item-BTC" }, { "id": "wait_btc", "action": "wait", "ms": 400 }, { "id": "back_1", "action": "press", "test_id": "perps-market-header-back-button" }, { "id": "open_eth", "action": "press", "test_id": "perps-market-row-item-ETH" }, { "id": "wait_eth", "action": "wait", "ms": 400 }, { "id": "back_2", "action": "press", "test_id": "perps-market-header-back-button" }, { "id": "open_sol", "action": "press", "test_id": "perps-market-row-item-SOL" }, { "id": "wait_sol", "action": "wait", "ms": 400 }, { "id": "back_3", "action": "press", "test_id": "perps-market-header-back-button" }, { "id": "open_hype", "action": "press", "test_id": "perps-market-row-item-HYPE" }, { "id": "wait_hype", "action": "wait", "ms": 400 }, { "id": "back_4", "action": "press", "test_id": "perps-market-header-back-button" }, { "id": "open_btc2", "action": "press", "test_id": "perps-market-row-item-BTC" }, { "id": "wait_btc2", "action": "wait", "ms": 400 }, { "id": "back_5", "action": "press", "test_id": "perps-market-header-back-button" }, { "id": "open_eth2", "action": "press", "test_id": "perps-market-row-item-ETH" }, { "id": "wait_eth2", "action": "wait", "ms": 400 }, { "id": "back_6", "action": "press", "test_id": "perps-market-header-back-button" }, { "id": "open_sol2", "action": "press", "test_id": "perps-market-row-item-SOL" }, { "id": "wait_sol2", "action": "wait", "ms": 400 }, { "id": "back_7", "action": "press", "test_id": "perps-market-header-back-button" }, { "id": "open_hype2", "action": "press", "test_id": "perps-market-row-item-HYPE" }, { "id": "wait_hype2", "action": "wait", "ms": 400 }, { "id": "back_8", "action": "press", "test_id": "perps-market-header-back-button" }, { "id": "settle", "action": "wait", "ms": 5000 }, { "id": "check_fix", "action": "log_watch", "window_seconds": 30, "watch_for": ["DEBUG-28141"], "must_not_appear": ["429 Too Many Requests", "rate limit", "Rate limit"] } ] } } }Pre-merge author checklist
Pre-merge reviewer checklist
Note
Medium Risk
Touches Perps streaming/subscription lifecycle (debouncing, retry, and cleanup) and changes initial candle fetch sizing; mistakes could cause missing/late market data or lingering subscriptions, though changes are localized and well-tested.
Overview
Reduces HyperLiquid rate-limit pressure during rapid Perps market switching by debouncing candle WebSocket connects, shrinking initial candle fetch durations, and cancelling in-flight candle snapshot requests on cleanup.
Adds race guards in
HyperLiquidSubscriptionServiceto prevent pending subscription promises (e.g.,activeAssetCtx,bbo,assetCtxs,dexAllMids) from becoming orphaned when cleanup happens before they resolve, and updates/expands unit tests to cover deferred connect retries, timer cancellation, abort handling, and stale-subscription cleanup.Written by Cursor Bugbot for commit 40fa684. This will update automatically on new commits. Configure here.