diff options
| author | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2024-01-07 01:21:06 -0700 |
|---|---|---|
| committer | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2024-01-07 01:21:06 -0700 |
| commit | db671d26c43e47b8285d319a0fd758df60d729c7 (patch) | |
| tree | 4cfc7e7b719d246637818e83feb8981255c19c67 /src/lib/utils/retry.ts | |
| parent | e1905622d7d8657aa7cd5bdfe9d06e4fbe40dc70 (diff) | |
| download | mistymountainstherapy-db671d26c43e47b8285d319a0fd758df60d729c7.tar.gz mistymountainstherapy-db671d26c43e47b8285d319a0fd758df60d729c7.zip | |
initial update with nodemailer
Diffstat (limited to 'src/lib/utils/retry.ts')
| -rw-r--r-- | src/lib/utils/retry.ts | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/lib/utils/retry.ts b/src/lib/utils/retry.ts new file mode 100644 index 0000000..34bc73b --- /dev/null +++ b/src/lib/utils/retry.ts @@ -0,0 +1,45 @@ +export type RetryStrategyF = (retries: number) => number; + +export const MAX_DEFAULT_RETRY_AMOUNT = 5; +export const WAIT_MS = 1_000; +export const RETRY_EXPONENT = 2; +export const RETRY_EXPONENTIAL_FACTOR = 1.1; +export const RETRY_JITTER_MAX = 3_000; + +const waitFor = (ms: number) => new Promise((res) => setTimeout(res, ms)); + +const exponentialStrategyWithJitter: RetryStrategyF = (retries: number) => + WAIT_MS * Math.pow(RETRY_EXPONENT, RETRY_EXPONENTIAL_FACTOR * retries) + + RETRY_JITTER_MAX * Math.random(); + +export const continueRetryUntilValidation = async <T>( + promiseFn: () => Promise<T> | T | Promise<void> | void, + validationFn: (x: T) => Promise<boolean> | boolean = (x: T) => + Promise.resolve(!!x), + maxRetries = MAX_DEFAULT_RETRY_AMOUNT, + waitTimeStrategy: RetryStrategyF = exponentialStrategyWithJitter, + retries = 0, + lastError: undefined | unknown = undefined +): Promise<T> => { + if (retries >= maxRetries) { + if (lastError) throw lastError; + throw new Error("Exceeded maximum retry amount"); + } + try { + if (retries) await waitFor(waitTimeStrategy(retries)); + + const res = await promiseFn(); + if (res && (await validationFn(res))) return res; + + throw new Error("Validation predicate unsuccessful"); + } catch (e: unknown) { + return continueRetryUntilValidation( + promiseFn, + validationFn, + maxRetries, + waitTimeStrategy, + retries + 1, + e + ); + } +};
\ No newline at end of file |
