UNPKG

@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.

128 lines 4.97 kB
/** * @module CircuitBreaker */ import {} from "../../../../backoff-policies/_module.js"; import { CIRCUIT_BREAKER_STATE, CLOSED_TRANSITIONS, HALF_OPEN_TRANSITIONS, } from "../../../../circuit-breaker/contracts/_module.js"; import { TimeSpan } from "../../../../time-span/implementations/_module.js"; import { callInvokable } from "../../../../utilities/_module.js"; /** * @internal */ export class CircuitBreakerPolicy { circuitBreakerPolicy; constructor(circuitBreakerPolicy) { this.circuitBreakerPolicy = circuitBreakerPolicy; } isMetricsEqual(metricsA, metricsB) { return this.circuitBreakerPolicy.isEqual?.(metricsA, metricsB) ?? false; } isEqual(stateA, stateB) { if (stateA.type === CIRCUIT_BREAKER_STATE.CLOSED && stateB.type === CIRCUIT_BREAKER_STATE.CLOSED) { return this.isMetricsEqual(stateA.metrics, stateB.metrics); } if (stateA.type === CIRCUIT_BREAKER_STATE.OPEN && stateB.type === CIRCUIT_BREAKER_STATE.OPEN) { return (stateA.attempt === stateB.attempt && stateA.startedAt === stateB.startedAt); } if (stateA.type === CIRCUIT_BREAKER_STATE.HALF_OPEN && stateB.type === CIRCUIT_BREAKER_STATE.HALF_OPEN) { return (stateA.attempt === stateB.attempt && this.isMetricsEqual(stateA.metrics, stateB.metrics)); } if (stateA.type === CIRCUIT_BREAKER_STATE.ISOLATED && stateB.type === CIRCUIT_BREAKER_STATE.ISOLATED) { return true; } return false; } initialState() { return { type: CIRCUIT_BREAKER_STATE.CLOSED, metrics: this.circuitBreakerPolicy.initialMetrics(), }; } whenClosed(currentState, currentDate) { const transition = this.circuitBreakerPolicy.whenClosed(currentState.metrics, new Date(currentDate)); if (transition === CLOSED_TRANSITIONS.NONE) { return currentState; } return { type: CIRCUIT_BREAKER_STATE.OPEN, attempt: 1, startedAt: new Date(currentDate).getTime(), }; } whenOpened(currentState, settings) { const waitTime = TimeSpan.fromTimeSpan(callInvokable(settings.backoffPolicy, currentState.attempt, null)); const endDate = waitTime.toEndDate(new Date(currentState.startedAt)); const isWaitTimeOver = endDate <= new Date(settings.currentDate); if (isWaitTimeOver) { return { type: CIRCUIT_BREAKER_STATE.HALF_OPEN, attempt: currentState.attempt, metrics: this.circuitBreakerPolicy.initialMetrics(), }; } return currentState; } whenHalfOpened(currentState, currentDate) { const transition = this.circuitBreakerPolicy.whenHalfOpened(currentState.metrics, new Date(currentDate)); if (transition === HALF_OPEN_TRANSITIONS.NONE) { return currentState; } if (transition === HALF_OPEN_TRANSITIONS.TO_CLOSED) { return { type: CIRCUIT_BREAKER_STATE.CLOSED, metrics: this.circuitBreakerPolicy.initialMetrics(), }; } return { type: CIRCUIT_BREAKER_STATE.OPEN, attempt: currentState.attempt + 1, startedAt: new Date(currentDate).getTime(), }; } trackSuccessWhenClosed(currentState, currentDate) { const newMetrics = this.circuitBreakerPolicy.trackSuccess(currentState, { currentDate: new Date(currentDate), initialMetrics: this.circuitBreakerPolicy.initialMetrics(), }); return { ...currentState, metrics: newMetrics, }; } trackFailureWhenClosed(currentState, currentDate) { const newMetrics = this.circuitBreakerPolicy.trackFailure(currentState, { currentDate: new Date(currentDate), initialMetrics: this.circuitBreakerPolicy.initialMetrics(), }); return { ...currentState, metrics: newMetrics, }; } trackSuccessWhenHalfOpened(currentState, currentDate) { const newMetrics = this.circuitBreakerPolicy.trackSuccess(currentState, { currentDate: new Date(currentDate), initialMetrics: this.circuitBreakerPolicy.initialMetrics(), }); return { ...currentState, metrics: newMetrics, }; } trackFailureWhenHalfOpened(currentState, currentDate) { const newMetrics = this.circuitBreakerPolicy.trackFailure(currentState, { currentDate: new Date(currentDate), initialMetrics: this.circuitBreakerPolicy.initialMetrics(), }); return { ...currentState, metrics: newMetrics, }; } } //# sourceMappingURL=circuit-breaker-policy.js.map