import { delay } from './delay'; 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 async function backoff(callback: () => Promise, opts?: { onError?: (e: any, failuresCount: number) => void, minDelay?: number, maxDelay?: number, maxFailureCount?: number }): Promise { 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); } } }