@zlattice/lattice-js
Version:
Lattice blockchain TypeScript SDK with dual module support (CJS + ESM)
126 lines • 4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RetryHandler = exports.ExponentialBackoffStrategy = exports.RandomDelayStrategy = exports.FixedDelayStrategy = void 0;
const logger_1 = require("../logger.js");
const index_1 = require("../utils/index.js");
/**
* FixedDelayStrategy
*/
class FixedDelayStrategy {
constructor(delay, // Fixed delay time (ms)
maxTimeout = Infinity) {
this.delay = delay;
this.maxTimeout = maxTimeout;
}
getDelay() {
return Math.min(this.delay, this.maxTimeout);
}
}
exports.FixedDelayStrategy = FixedDelayStrategy;
/**
* Default fixed delay strategy
*/
FixedDelayStrategy.default = new FixedDelayStrategy(500, 1000);
/**
* RandomDelayStrategy
*/
class RandomDelayStrategy {
constructor(minDelay, // Minimum delay time (ms)
maxDelay, // Maximum delay time (ms)
maxTimeout = Infinity) {
this.minDelay = minDelay;
this.maxDelay = maxDelay;
this.maxTimeout = maxTimeout;
if (minDelay > maxDelay) {
throw new Error("minDelay must be less than or equal to maxDelay");
}
}
getDelay() {
// Generate random delay between minDelay and maxDelay
const delay = this.minDelay + Math.random() * (this.maxDelay - this.minDelay);
return Math.min(delay, this.maxTimeout);
}
}
exports.RandomDelayStrategy = RandomDelayStrategy;
/**
* Default random delay strategy
*/
RandomDelayStrategy.default = new RandomDelayStrategy(300, 1000, 2000);
/**
* ExponentialBackoffStrategy
*/
class ExponentialBackoffStrategy {
constructor(baseDelay, // Base delay time (ms)
factor, // Exponential factor
maxTimeout = Infinity, randomize = false // Whether to add random jitter
) {
this.baseDelay = baseDelay;
this.factor = factor;
this.maxTimeout = maxTimeout;
this.randomize = randomize;
}
getDelay(attempt) {
let delay = this.baseDelay * this.factor ** (attempt - 1);
if (this.randomize) {
// Add random jitter (50%~150%)
delay *= 0.5 + Math.random();
}
return Math.min(delay, this.maxTimeout);
}
}
exports.ExponentialBackoffStrategy = ExponentialBackoffStrategy;
/**
* Default exponential backoff strategy
*/
ExponentialBackoffStrategy.default = new ExponentialBackoffStrategy(300, 2, 5000, true);
/**
* RetryHandler
*/
class RetryHandler {
constructor(strategy, // Retry strategy
retries, // Maximum retry times
onRetry // Retry callback
) {
this.strategy = strategy;
this.retries = retries;
this.onRetry = onRetry;
}
/**
* Execute the async function and retry according to the strategy
* @param fn The async function to execute
* @returns The result of the async function
*/
async execute(fn) {
const delayFn = (status) => {
const nextDelay = this.strategy.getDelay(status.index + 1);
if (status.error) {
this.onRetry?.(status.error, status.index);
}
return nextDelay;
};
const retryFn = (status) => {
if (status.index >= this.retries) {
return false;
}
if (status.error &&
status.error instanceof Error &&
status.error.message.includes("Bad request")) {
return false;
}
return true;
};
const errorFn = (status) => {
if (status.error) {
logger_1.log.error(`Retry failed after attempt #${status.index}, duration: ${status.duration}ms, error: ${status.error.message}`);
}
};
const wrappedFn = (_) => fn();
return (0, index_1.retryAsync)(wrappedFn, {
retry: retryFn,
delay: delayFn,
error: errorFn
});
}
}
exports.RetryHandler = RetryHandler;
//# sourceMappingURL=retry_handler.js.map