Skip to content

Instantly share code, notes, and snippets.

@johncmunson
Last active September 8, 2020 22:24
Show Gist options
  • Save johncmunson/d56e020180d672bcfe88346dcdd4397b to your computer and use it in GitHub Desktop.
Save johncmunson/d56e020180d672bcfe88346dcdd4397b to your computer and use it in GitHub Desktop.
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