Last active
September 8, 2020 22:24
-
-
Save johncmunson/d56e020180d672bcfe88346dcdd4397b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const getRandomBool = () => Math.random() >= 0.5 | |
const getJitterMultiplier = (min: number, max: number): number => { | |
const percent = (Math.random() * (max - min) + min) / 100 | |
return getRandomBool() ? 1 + percent : 1 - percent | |
} | |
const asyncRetry = async (fn, opts = {}) => { | |
const defaultOpts = { retries: 5, interval: 100, exponential: false, jitter: false } | |
opts = { ...defaultOpts, ...opts } | |
try { | |
const val = await fn(opts.retries) | |
return val | |
} catch (error) { | |
if (opts.retries) { | |
await new Promise(r => setTimeout(r, opts.interval)) | |
let newInterval = opts.interval | |
if (opts.exponential) { | |
newInterval *= 2 | |
} | |
if (opts.jitter) { | |
newInterval *= getJitterMultiplier(0, 10) | |
} | |
return asyncRetry(fn, { | |
retries: opts.retries - 1, | |
interval: newInterval, | |
exponential: opts.exponential, | |
}) | |
} else throw error | |
} | |
} | |
// Usage... | |
const widgets = await asyncRetry( | |
async attemptsLeft => { | |
const widgets = await fetch('www.example.com/widgets') | |
if (widgets.length === 0) { | |
console.log(`${attemptsLeft} attempts left`) | |
throw Error('Widgets not yet available') | |
} | |
return widgets | |
}, | |
{ retries: 30, interval: 10000, exponential: false, jitter: false } | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment