Skip to content

Instantly share code, notes, and snippets.

@1mursaleen
Last active February 23, 2023 12:18
Show Gist options
  • Save 1mursaleen/b17c154884aa85929aa554bb8a363e84 to your computer and use it in GitHub Desktop.
Save 1mursaleen/b17c154884aa85929aa554bb8a363e84 to your computer and use it in GitHub Desktop.
TypeScipt Recurring Retry Function - with Exponential Backoff - for Synchronous & Asynchronous Functions
export const randomString = (length: number): string => {
let result = "";
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const charactersLength = characters.length;
let counter = 0;
while (counter < length) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
counter += 1;
}
return result;
};
export default randomString;
import randomString from "./randomString";
import Sleep from "./Sleep";
interface IRetryHelperOptions {
retries?: number;
retryIntervalMs?: number;
backoffIteration?: number;
trialID?: string | undefined;
exponentialBackoff?: boolean;
logs?: boolean;
}
/**
* Runs 'RetryFunction' & retries automatically if it fails.
*
* Tries max '1 + retries' times,
* with 'retryIntervalMs' milliseconds between retries.
* From https://mtsknn.fi/blog/js-retry-on-fail/
*
* @param RetryFunction
* @param options
* @returns Promise
*/
export const RetryHelper = async <T>(
RetryFunction: () => Promise<T> | T,
{
retries = 3,
retryIntervalMs = 500,
logs = false,
trialID = randomString(5),
exponentialBackoff = false,
backoffIteration = 0,
}: IRetryHelperOptions,
): Promise<T> => {
try {
logs && console.log(trialID, " Trying... ");
return await RetryFunction();
} catch (error) {
// Retries Exhausted
if (retries <= 0) {
logs && console.log(trialID, " Retry ", retries, " Exhausted");
throw error;
}
logs && console.log(trialID, " Retry ", retries);
backoffIteration = exponentialBackoff ? backoffIteration + 1 : 1;
await Sleep(retryIntervalMs * backoffIteration);
return RetryHelper(RetryFunction, {
retries: retries - 1,
exponentialBackoff,
backoffIteration,
retryIntervalMs,
trialID,
logs,
});
}
};
/**
* Retry Test function.
*
* @returns Promise
*/
export const TestFunction = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const number = Math.floor(Math.random() * 10);
// will work ~ 30% times
if (number >= 7) {
return reject("RETRY TEST FUNCTION - FAILED");
} else {
return resolve("RETRY TEST FUNCTION - PASSED");
}
}, 500);
});
};
// RetryHelper(TestFunction);
export default RetryHelper;
/**
* Sleep function for delay.
*
* @param ms number
* @returns Promise
*/
export const Sleep = (ms: number = 500) =>
new Promise((resolve) => setTimeout(resolve, ms));
export default Sleep;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment