refactor: update JsonRpcCallOptions to use maxAttempts and attemptTimeoutMs, implement exponential backoff for retries

This commit is contained in:
Adam Shiervani 2025-10-27 12:03:47 +01:00
parent 5f394d8e9f
commit a018ba36b4
1 changed files with 13 additions and 11 deletions

View File

@ -6,8 +6,8 @@ import { sleep } from "@/utils";
export interface JsonRpcCallOptions { export interface JsonRpcCallOptions {
method: string; method: string;
params?: unknown; params?: unknown;
timeout?: number; attemptTimeoutMs?: number;
retriesOnError?: number; maxAttempts?: number;
} }
export interface JsonRpcCallResponse<T = unknown> { export interface JsonRpcCallResponse<T = unknown> {
@ -93,13 +93,16 @@ export function callJsonRpc(
export async function callJsonRpc<T = unknown>( export async function callJsonRpc<T = unknown>(
options: JsonRpcCallOptions, options: JsonRpcCallOptions,
): Promise<JsonRpcCallResponse<T>> { ): Promise<JsonRpcCallResponse<T>> {
const maxRetries = options.retriesOnError ?? 0; const maxAttempts = options.maxAttempts ?? 1;
const timeout = options.timeout || 5000; const timeout = options.attemptTimeoutMs || 5000;
for (let attempt = 0; attempt <= maxRetries; attempt++) { for (let attempt = 0; attempt < maxAttempts; attempt++) {
const abortController = new AbortController(); const abortController = new AbortController();
const timeoutId = setTimeout(() => abortController.abort(), timeout); const timeoutId = setTimeout(() => abortController.abort(), timeout);
// Exponential backoff for retries that starts at 500ms up to a maximum of 10 seconds
const backoffMs = Math.min(500 * Math.pow(2, attempt), 10000);
try { try {
// Wait for RTC readiness // Wait for RTC readiness
const rpcDataChannel = await waitForRtcReady(abortController.signal); const rpcDataChannel = await waitForRtcReady(abortController.signal);
@ -114,8 +117,8 @@ export async function callJsonRpc<T = unknown>(
clearTimeout(timeoutId); clearTimeout(timeoutId);
// Retry on error if attempts remain // Retry on error if attempts remain
if (response.error && attempt < maxRetries) { if (response.error && attempt < maxAttempts - 1) {
await sleep(1000); await sleep(backoffMs);
continue; continue;
} }
@ -124,8 +127,8 @@ export async function callJsonRpc<T = unknown>(
clearTimeout(timeoutId); clearTimeout(timeoutId);
// Retry on timeout/error if attempts remain // Retry on timeout/error if attempts remain
if (attempt < maxRetries) { if (attempt < maxAttempts - 1) {
await sleep(1000); await sleep(backoffMs);
continue; continue;
} }
@ -194,8 +197,7 @@ export async function getUpdateStatus() {
// This function calls our api server to see if there are any updates available. // This function calls our api server to see if there are any updates available.
// It can be called on page load right after a restart, so we need to give it time to // It can be called on page load right after a restart, so we need to give it time to
// establish a connection to the api server. // establish a connection to the api server.
timeout: 10000, maxAttempts: 6,
retriesOnError: 5,
}); });
if (response.error) throw response.error; if (response.error) throw response.error;