Skip to content

refactor: implement fallback API connection#2020

Open
AMIRKHANEF wants to merge 3 commits intoPolkaGate:mainfrom
AMIRKHANEF:ApiFallback
Open

refactor: implement fallback API connection#2020
AMIRKHANEF wants to merge 3 commits intoPolkaGate:mainfrom
AMIRKHANEF:ApiFallback

Conversation

@AMIRKHANEF
Copy link
Member

@AMIRKHANEF AMIRKHANEF commented Nov 10, 2025

Close: #2015

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced API connection reliability with exponential backoff retry logic for failed connections, capping retry attempts at a maximum threshold.
    • Improved auto-mode endpoint fallback handling to better manage connection failures and error recovery.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 10, 2025

Walkthrough

Refactors ApiProvider connection flow to async/await, adds MAX_RETRIES and exponential backoff, makes connection attempts sequential (awaiting handleAutoMode, connectToEndpoint, connectToLightClient), updates connectToEndpoint to use throwOnConnect and explicit disconnect/reset on failure, and adds retry/fallback to AUTO_MODE_DEFAULT_ENDPOINT with bounded retries.

Changes

Cohort / File(s) Summary
Api connection logic
packages/extension-ui/src/Popup/contexts/ApiProvider.tsx
Introduced MAX_RETRIES; getApi signature extended with retryCount?: number and performs exponential-backoff retries up to MAX_RETRIES, returning undefined after; requestApiConnection made async and now awaits handleAutoMode, connectToEndpoint, and connectToLightClient sequentially; connectToEndpoint creates WsProvider/ApiPromise with throwOnConnect: true, disconnects and resolves pending connections as undefined on failure, and resets endpoint to AUTO_MODE_DEFAULT_ENDPOINT when in auto mode; logging adjusted for retry/backoff flow.

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant getApi
    participant requestApiConnection as requestApiConnection<br/>(async)
    participant handleAutoMode
    participant connectToEndpoint
    participant connectToLightClient

    Caller->>getApi: getApi(genesisHash,endpoints, retryCount?)
    alt No endpoint selected
        getApi->>getApi: set AUTO_MODE_DEFAULT_ENDPOINT if needed
    end
    getApi->>requestApiConnection: await requestApiConnection()
    rect rgb(220, 235, 255)
        Note over requestApiConnection: Sequential connection steps
        requestApiConnection->>handleAutoMode: await handleAutoMode()
        handleAutoMode-->>requestApiConnection: resolved endpoint
        requestApiConnection->>connectToEndpoint: await connectToEndpoint() (throwOnConnect:true)
        alt connect success
            connectToEndpoint-->>requestApiConnection: ApiPromise
            requestApiConnection->>connectToLightClient: await connectToLightClient()
            connectToLightClient-->>requestApiConnection: light client ready
        else connect failure
            connectToEndpoint->>connectToEndpoint: disconnect wsProvider, reset endpoint if AUTO
            connectToEndpoint-->>requestApiConnection: throw error
        end
    end
    rect rgb(255, 235, 230)
        Note over getApi: Retry & backoff
        requestApiConnection-->>getApi: success or error
        alt error
            getApi->>getApi: log, wait (exponential backoff)
            getApi->>getApi: if retryCount < MAX_RETRIES -> recursive getApi(retryCount+1)
        else success
            getApi-->>Caller: return ApiPromise
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • verify exponential backoff math and bounds for MAX_RETRIES
    • ensure recursive getApi retries cannot cause unbounded recursion/state corruption
    • confirm wsProvider lifecycle: creation, disconnect, and cleanup on failure
    • check that awaiting handleAutoMode eliminates prior race conditions and that state mutations are safe
    • validate that pending connection resolvers are consistently resolved to undefined on failure

Poem

🐰
I hopped through sockets, one by one,
Awaiting each connect till done,
If endpoints trip, I nudge to “auto”,
Retry with care, then gently go,
A rabbit’s sequence, steady, fun.

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: implementing fallback API connection logic, which directly aligns with the core objective.
Linked Issues check ✅ Passed The pull request implements fallback API connection with auto-mode switching when endpoints fail, matching the primary objective in issue #2015.
Out of Scope Changes check ✅ Passed All changes in ApiProvider.tsx are directly related to implementing the fallback mechanism with retry logic and auto-mode handling as specified in issue #2015.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
packages/extension-ui/src/Popup/contexts/ApiProvider.tsx (1)

284-285: Update comment for clarity.

The comment says "Start connection" but the await means the code waits for the connection to complete, not just initiate it.

Apply this diff:

-      // Start connection
+      // Request connection and wait for completion
       await requestApiConnection(genesisHash, endpoint, endpoints);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e22bf0f and db9bc02.

📒 Files selected for processing (1)
  • packages/extension-ui/src/Popup/contexts/ApiProvider.tsx (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/extension-ui/src/Popup/contexts/ApiProvider.tsx (2)
packages/extension-polkagate/src/util/constants.ts (1)
  • AUTO_MODE_DEFAULT_ENDPOINT (270-275)
packages/extension-polkagate/src/util/types.ts (2)
  • EndpointType (894-899)
  • DropdownOption (876-879)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: Analyze (javascript)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/extension-ui/src/Popup/contexts/ApiProvider.tsx (1)

16-16: Reuse shared MAX_RETRIES constant.

There is already a MAX_RETRIES exported from packages/extension-polkagate/src/util/api/utils.ts (value 7). Redefining a different value here risks divergence and makes tuning harder to reason about. Prefer importing the shared constant (or centralizing configuration) so retry limits stay consistent across the codebase.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db9bc02 and d81910c.

📒 Files selected for processing (1)
  • packages/extension-ui/src/Popup/contexts/ApiProvider.tsx (5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-08-31T05:19:02.468Z
Learnt from: AMIRKHANEF
Repo: PolkaGate/extension PR: 1467
File: packages/extension-polkagate/src/util/types.ts:0-0
Timestamp: 2024-08-31T05:19:02.468Z
Learning: The `SavedEndpoint` interface in the `packages/extension-polkagate/src/util/types.ts` file has a property named `isOnManual`, which indicates whether the endpoint is in manual mode.

Applied to files:

  • packages/extension-ui/src/Popup/contexts/ApiProvider.tsx
🧬 Code graph analysis (1)
packages/extension-ui/src/Popup/contexts/ApiProvider.tsx (3)
packages/extension-polkagate/src/util/api/utils.ts (1)
  • MAX_RETRIES (5-5)
packages/extension-polkagate/src/util/constants.ts (1)
  • AUTO_MODE_DEFAULT_ENDPOINT (270-275)
packages/extension-polkagate/src/util/types.ts (2)
  • EndpointType (894-899)
  • DropdownOption (876-879)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build

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.

Fallback API connection to auto mode if selected or previously best endpoint fails

2 participants