OpenGlass/sources/utils/time.ts

46 lines
1.7 KiB
TypeScript

export async function delay(milliseconds: number): Promise<void> {
return new Promise((resolve) => {
setTimeout(resolve, milliseconds);
});
}
export function exponentialBackoffDelay(currentFailureCount: number, minDelay: number, maxDelay: number, maxFailureCount: number) {
let maxDelayRet = minDelay + ((maxDelay - minDelay) / maxFailureCount) * Math.max(currentFailureCount, maxFailureCount);
return Math.round(Math.random() * maxDelayRet);
}
export type BackoffFunc = <T>(callback: () => Promise<T>) => Promise<T>;
export function createBackoff(
opts?: {
onError?: (e: any, failuresCount: number) => void,
minDelay?: number,
maxDelay?: number,
maxFailureCount?: number
}): BackoffFunc {
return async <T>(callback: () => Promise<T>): Promise<T> => {
let currentFailureCount = 0;
const minDelay = opts && opts.minDelay !== undefined ? opts.minDelay : 250;
const maxDelay = opts && opts.maxDelay !== undefined ? opts.maxDelay : 1000;
const maxFailureCount = opts && opts.maxFailureCount !== undefined ? opts.maxFailureCount : 50;
while (true) {
try {
return await callback();
} catch (e) {
if (currentFailureCount < maxFailureCount) {
currentFailureCount++;
}
if (opts && opts.onError) {
opts.onError(e, currentFailureCount);
}
let waitForRequest = exponentialBackoffDelay(currentFailureCount, minDelay, maxDelay, maxFailureCount);
await delay(waitForRequest);
}
}
};
}
export const backoff = createBackoff({
onError(e, failuresCount) {
console.warn(e);
},
});