@daiso-tech/core
Version:
The library offers flexible, framework-agnostic solutions for modern web applications, built on adaptable components that integrate seamlessly with popular frameworks like Next Js.
97 lines • 3.36 kB
JavaScript
/**
* @module CircuitBreaker
*/
import { CIRCUIT_BREAKER_STATE, HALF_OPEN_TRANSITIONS, CLOSED_TRANSITIONS, } from "../../../../circuit-breaker/contracts/_module.js";
/**
* @internal
*/
function validateFailureThreshold(failureThreshold) {
if (!Number.isSafeInteger(failureThreshold)) {
throw new TypeError(`"ConsecutiveBreakerSettings.failureThreshold" should be an integer, got float instead`);
}
if (failureThreshold < 1) {
throw new RangeError(`"ConsecutiveBreakerSettings.failureThreshold" should be a positive, got ${String(failureThreshold)}`);
}
}
/**
* @internal
*/
function validateSuccessThreshold(successThreshold) {
if (!Number.isSafeInteger(successThreshold)) {
throw new TypeError(`"ConsecutiveBreakerSettings.successThreshold" should be an integer, got float instead`);
}
if (successThreshold < 1) {
throw new RangeError(`"ConsecutiveBreakerSettings.successThreshold" should be a positive, got ${String(successThreshold)}`);
}
}
/**
* @internal
*/
export function resolveConsecutiveBreakerSettings(settings) {
const { failureThreshold = 5, successThreshold = failureThreshold } = settings;
validateFailureThreshold(failureThreshold);
validateSuccessThreshold(successThreshold);
return {
failureThreshold,
successThreshold,
};
}
/**
* The `ConsecutiveBreaker` breaks after n requests in a row fail.
*
* IMPORT_PATH: `"@daiso-tech/core/circuit-breaker/policies"`
* @group Policies
*/
export class ConsecutiveBreaker {
failureThreshold;
successThreshold;
constructor(settings = {}) {
const { failureThreshold, successThreshold } = resolveConsecutiveBreakerSettings(settings);
this.failureThreshold = failureThreshold;
this.successThreshold = successThreshold;
}
initialMetrics() {
return {
failureCount: 0,
successCount: 0,
};
}
whenClosed(currentMetrics, _currentDate) {
const hasFailed = currentMetrics.failureCount >= this.failureThreshold;
if (hasFailed) {
return CLOSED_TRANSITIONS.TO_OPEN;
}
return CLOSED_TRANSITIONS.NONE;
}
whenHalfOpened(currentMetrics, _currentDate) {
const hasFailed = currentMetrics.failureCount > 0;
if (hasFailed) {
return HALF_OPEN_TRANSITIONS.TO_OPEN;
}
const hasSucceeded = currentMetrics.successCount >= this.successThreshold;
if (hasSucceeded) {
return HALF_OPEN_TRANSITIONS.TO_CLOSED;
}
return HALF_OPEN_TRANSITIONS.NONE;
}
trackFailure(currentState, _settings) {
return {
failureCount: currentState.metrics.failureCount + 1,
successCount: currentState.metrics.successCount,
};
}
trackSuccess(currentState, settings) {
if (currentState.type === CIRCUIT_BREAKER_STATE.CLOSED) {
return settings.initialMetrics;
}
return {
failureCount: currentState.metrics.failureCount,
successCount: currentState.metrics.successCount + 1,
};
}
isEqual(metricsA, metricsB) {
return (metricsA.failureCount === metricsB.failureCount &&
metricsA.successCount === metricsB.successCount);
}
}
//# sourceMappingURL=consecutive-breaker.js.map