network: Utility to retry network operation with backoff

This commit is contained in:
Valere
2025-03-10 17:54:44 +01:00
parent c22412c045
commit 343da0db14

View File

@@ -8,6 +8,7 @@ Please see LICENSE in the repository root for full details.
import { IndexedDBStore } from "matrix-js-sdk/src/store/indexeddb";
import { MemoryStore } from "matrix-js-sdk/src/store/memory";
import {
calculateRetryBackoff,
createClient,
type ICreateClientOpts,
Preset,
@@ -17,6 +18,7 @@ import { ClientEvent } from "matrix-js-sdk/src/client";
import { type ISyncStateData, type SyncState } from "matrix-js-sdk/src/sync";
import { logger } from "matrix-js-sdk/src/logger";
import { secureRandomBase64Url } from "matrix-js-sdk/src/randomstring";
import { sleep } from "matrix-js-sdk/src/utils";
import type { MatrixClient } from "matrix-js-sdk/src/client";
import type { Room } from "matrix-js-sdk/src/models/room";
@@ -336,3 +338,30 @@ export function getRelativeRoomUrl(
: "";
return `/room/#${roomPart}?${generateUrlSearchParams(roomId, encryptionSystem, viaServers).toString()}`;
}
/**
* Perfom a network operation with retries on ConnectionError.
* If the error is not retryable, or the max number of retries is reached, the error is rethrown.
* Supports handling of matrix quotas.
*/
export async function doNetworkOperationWithRetry<T>(
operation: () => Promise<T>,
): Promise<T> {
let currentRetryCount = 0;
// eslint-disable-next-line no-constant-condition
while (true) {
try {
return await operation();
} catch (e) {
currentRetryCount++;
const backoff = calculateRetryBackoff(e, currentRetryCount, true);
if (backoff < 0) {
// Max number of retries reached, or error is not retryable. rethrow the error
throw e;
}
// wait for the specified time and then retry the request
await sleep(backoff);
}
}
}