Skip to content

Instantly share code, notes, and snippets.

@snewcomer
Created April 16, 2020 17:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snewcomer/25ff8744927b1ddc008efac8570ed310 to your computer and use it in GitHub Desktop.
Save snewcomer/25ff8744927b1ddc008efac8570ed310 to your computer and use it in GitHub Desktop.
exponential-backoff
function createScheduler({
callback,
time,
callbackTimeout,
backoffMultiplier = 1.5,
backoffMaxTime = 20000
}) {
let run;
let timeoutId;
let ticker;
function pause(time) {
return new Promise(resolve => {
timeoutId = setTimeout(resolve, time);
});
}
async function* cycle(time) {
let currentWaitTime = time;
run = true;
while (run) {
const error = yield pause(currentWaitTime);
if (error) {
currentWaitTime = Math.min(
currentWaitTime * backoffMultiplier,
backoffMaxTime
);
} else {
currentWaitTime = Math.max(currentWaitTime / backoffMultiplier, time);
}
}
}
async function runPeriodically() {
if (!ticker || !run) {
ticker = cycle(time);
}
let item = await ticker.next();
while (!item.done) {
try {
if (callbackTimeout) {
await Promise.race([
callback(),
pause(callbackTimeout).then(() => {
throw new Error("Callback timeout");
})
]);
} else {
await callback();
}
item = await ticker.next();
} catch (error) {
item = await ticker.next(error);
}
}
}
function stop() {
clearTimeout(timeoutId);
run = false;
}
return {
runPeriodically,
stop
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment