UNPKG

@shopify/cli-kit

Version:

A set of utilities, interfaces, and models that are common across all the platform features

64 lines 2.27 kB
import { sleep } from '../../public/node/system.js'; const DEFAULT_RETRY_DELAY_MS = 300; // 10 seconds default export const DEFAULT_MAX_TIME_MS = 10000; /** * Calculates the delay for a given attempt in exponential backoff * * First result is zero, second result is firstDelayMs, third result is firstDelay * 2, then * 4, then * 8, etc. * * Delays are capped by a maximum value. */ function calculateBackoffDelay(attempt, firstDelayMs, maximumDelayMs = DEFAULT_MAX_TIME_MS / 3) { if (attempt === 0) { return 0; } const delayMultiplier = 2 ** (attempt - 1); return Math.min(firstDelayMs * delayMultiplier, maximumDelayMs); } /** * Common generator function for backoff implementations */ async function* backoffGenerator(shouldContinue, firstDelayMs) { let attempt = 0; while (true) { const nextDelayMs = calculateBackoffDelay(attempt, firstDelayMs); if (!shouldContinue(nextDelayMs)) { return { remainingMs: 0, iterations: attempt }; } // eslint-disable-next-line no-await-in-loop await sleep(nextDelayMs / 1000); yield nextDelayMs; attempt++; } } /** * Generator that sleeps with exponential backoff between yields, stopping before exceeding a time limit * * Yields the amount of time slept in milliseconds. * * @param maxTimeMs - Maximum total time in milliseconds before stopping * @param firstDelayMs - First delay in milliseconds * @returns Information about the backoff sequence: remaining time and iteration count */ export async function* sleepWithBackoffUntil(maxTimeMs = DEFAULT_MAX_TIME_MS, firstDelayMs = DEFAULT_RETRY_DELAY_MS) { if (maxTimeMs <= 0) { return { remainingMs: 0, iterations: 0 }; } const startTime = Date.now(); const generator = backoffGenerator((nextDelay) => { const elapsedTime = Date.now() - startTime; return elapsedTime + nextDelay <= maxTimeMs; }, firstDelayMs); let attempt = 0; for await (const delayMs of generator) { yield delayMs; attempt++; } const elapsedTime = Date.now() - startTime; return { remainingMs: maxTimeMs - elapsedTime, iterations: attempt, }; } //# sourceMappingURL=sleep-with-backoff.js.map