1 | import { NO_RETRY_INCREMENT, RETRY_COST, TIMEOUT_RETRY_COST } from "./constants";
|
2 | export const getDefaultRetryQuota = (initialRetryTokens, options) => {
|
3 | const MAX_CAPACITY = initialRetryTokens;
|
4 | const noRetryIncrement = options?.noRetryIncrement ?? NO_RETRY_INCREMENT;
|
5 | const retryCost = options?.retryCost ?? RETRY_COST;
|
6 | const timeoutRetryCost = options?.timeoutRetryCost ?? TIMEOUT_RETRY_COST;
|
7 | let availableCapacity = initialRetryTokens;
|
8 | const getCapacityAmount = (error) => (error.name === "TimeoutError" ? timeoutRetryCost : retryCost);
|
9 | const hasRetryTokens = (error) => getCapacityAmount(error) <= availableCapacity;
|
10 | const retrieveRetryTokens = (error) => {
|
11 | if (!hasRetryTokens(error)) {
|
12 | throw new Error("No retry token available");
|
13 | }
|
14 | const capacityAmount = getCapacityAmount(error);
|
15 | availableCapacity -= capacityAmount;
|
16 | return capacityAmount;
|
17 | };
|
18 | const releaseRetryTokens = (capacityReleaseAmount) => {
|
19 | availableCapacity += capacityReleaseAmount ?? noRetryIncrement;
|
20 | availableCapacity = Math.min(availableCapacity, MAX_CAPACITY);
|
21 | };
|
22 | return Object.freeze({
|
23 | hasRetryTokens,
|
24 | retrieveRetryTokens,
|
25 | releaseRetryTokens,
|
26 | });
|
27 | };
|