This repository has been archived on 2024-09-11. You can view files and clone it, but cannot push or open issues or pull requests.
svrjs-blog-newsletter/cronjob/node_modules/@smithy/util-retry/dist-es/StandardRetryStrategy.js
2024-05-26 22:54:55 +02:00

65 lines
2.9 KiB
JavaScript

import { DEFAULT_MAX_ATTEMPTS, RETRY_MODES } from "./config";
import { DEFAULT_RETRY_DELAY_BASE, INITIAL_RETRY_TOKENS, NO_RETRY_INCREMENT, RETRY_COST, THROTTLING_RETRY_DELAY_BASE, TIMEOUT_RETRY_COST, } from "./constants";
import { getDefaultRetryBackoffStrategy } from "./defaultRetryBackoffStrategy";
import { createDefaultRetryToken } from "./defaultRetryToken";
export class StandardRetryStrategy {
constructor(maxAttempts) {
this.maxAttempts = maxAttempts;
this.mode = RETRY_MODES.STANDARD;
this.capacity = INITIAL_RETRY_TOKENS;
this.retryBackoffStrategy = getDefaultRetryBackoffStrategy();
this.maxAttemptsProvider = typeof maxAttempts === "function" ? maxAttempts : async () => maxAttempts;
}
async acquireInitialRetryToken(retryTokenScope) {
return createDefaultRetryToken({
retryDelay: DEFAULT_RETRY_DELAY_BASE,
retryCount: 0,
});
}
async refreshRetryTokenForRetry(token, errorInfo) {
const maxAttempts = await this.getMaxAttempts();
if (this.shouldRetry(token, errorInfo, maxAttempts)) {
const errorType = errorInfo.errorType;
this.retryBackoffStrategy.setDelayBase(errorType === "THROTTLING" ? THROTTLING_RETRY_DELAY_BASE : DEFAULT_RETRY_DELAY_BASE);
const delayFromErrorType = this.retryBackoffStrategy.computeNextBackoffDelay(token.getRetryCount());
const retryDelay = errorInfo.retryAfterHint
? Math.max(errorInfo.retryAfterHint.getTime() - Date.now() || 0, delayFromErrorType)
: delayFromErrorType;
const capacityCost = this.getCapacityCost(errorType);
this.capacity -= capacityCost;
return createDefaultRetryToken({
retryDelay,
retryCount: token.getRetryCount() + 1,
retryCost: capacityCost,
});
}
throw new Error("No retry token available");
}
recordSuccess(token) {
this.capacity = Math.max(INITIAL_RETRY_TOKENS, this.capacity + (token.getRetryCost() ?? NO_RETRY_INCREMENT));
}
getCapacity() {
return this.capacity;
}
async getMaxAttempts() {
try {
return await this.maxAttemptsProvider();
}
catch (error) {
console.warn(`Max attempts provider could not resolve. Using default of ${DEFAULT_MAX_ATTEMPTS}`);
return DEFAULT_MAX_ATTEMPTS;
}
}
shouldRetry(tokenToRenew, errorInfo, maxAttempts) {
const attempts = tokenToRenew.getRetryCount() + 1;
return (attempts < maxAttempts &&
this.capacity >= this.getCapacityCost(errorInfo.errorType) &&
this.isRetryableError(errorInfo.errorType));
}
getCapacityCost(errorType) {
return errorType === "TRANSIENT" ? TIMEOUT_RETRY_COST : RETRY_COST;
}
isRetryableError(errorType) {
return errorType === "THROTTLING" || errorType === "TRANSIENT";
}
}