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.

131 lines (125 loc) 5.3 kB
/** * @module CircuitBreaker */ import {} from "ioredis"; import { BACKOFFS, resolveBackoffSettingsEnum, serializeBackoffSettingsEnum, } from "../../../../backoff-policies/_module.js"; import { CIRCUIT_BREAKER_STATE, } from "../../../../circuit-breaker/contracts/_module.js"; import {} from "../../../../circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/circuit-breaker-policy.js"; import { circuitBreakerFactoryLua } from "../../../../circuit-breaker/implementations/adapters/redis-circuit-breaker-adapter/lua/_module.js"; import { BREAKER_POLICIES, resolveCircuitBreakerPolicySettings, serializeCircuitBreakerPolicySettingsEnum, } from "../../../../circuit-breaker/implementations/policies/_module.js"; /** * IMPORT_PATH: `"@daiso-tech/core/circuit-breaker/redis-circuit-breaker-adapter"` * @group Adapters */ export class RedisCircuitBreakerAdapter { backoff; policy; database; /** * @example * ```ts * import { RedisCircuitBreakerAdapter } from "@daiso-tech/core/circuit-breaker/redis-circuit-breaker-adapter"; * import Redis from "ioredis"; * * const database = new Redis("YOUR_REDIS_CONNECTION_STRING"); * const circuitBreakerAdapter = new RedisCircuitBreakerAdapter({ * database * }); * ``` */ constructor(settings) { const { database, backoff = { type: BACKOFFS.EXPONENTIAL, }, policy = { type: BREAKER_POLICIES.CONSECUTIVE, }, } = settings; this.database = database; this.backoff = resolveBackoffSettingsEnum(backoff); this.policy = resolveCircuitBreakerPolicySettings(policy); this.initUpdateStateCommmand(); this.initTrackFailureCommmand(); this.initTrackSuccessCommmand(); } initUpdateStateCommmand() { if (typeof this.database.daiso_circuit_breaker_update_state === "function") { return; } this.database.defineCommand("daiso_circuit_breaker_update_state", { numberOfKeys: 1, lua: ` ${circuitBreakerFactoryLua} local key = KEYS[1]; local backoffSettings = cjson.decode(ARGV[1]); local policySettings = cjson.decode(ARGV[2]); local currentDate = tonumber(ARGV[3]); local circuitBreaker = circuitBreakerFactory(backoffSettings, policySettings, currentDate) local transition = circuitBreaker.updateState(key) return cjson.encode(transition) `, }); } initTrackFailureCommmand() { if (typeof this.database.daiso_circuit_breaker_track_failure === "function") { return; } this.database.defineCommand("daiso_circuit_breaker_track_failure", { numberOfKeys: 1, lua: ` ${circuitBreakerFactoryLua} local key = KEYS[1]; local backoffSettings = cjson.decode(ARGV[1]); local policySettings = cjson.decode(ARGV[2]); local currentDate = tonumber(ARGV[3]); local circuitBreaker = circuitBreakerFactory(backoffSettings, policySettings, currentDate) circuitBreaker.trackFailure(key) `, }); } initTrackSuccessCommmand() { if (typeof this.database.daiso_circuit_breaker_track_success === "function") { return; } this.database.defineCommand("daiso_circuit_breaker_track_success", { numberOfKeys: 1, lua: ` ${circuitBreakerFactoryLua} local key = KEYS[1]; local backoffSettings = cjson.decode(ARGV[1]); local policySettings = cjson.decode(ARGV[2]); local currentDate = tonumber(ARGV[3]); local circuitBreaker = circuitBreakerFactory(backoffSettings, policySettings, currentDate) circuitBreaker.trackSuccess(key) `, }); } async getState(key) { const value = await this.database.get(key); if (value === null) { return CIRCUIT_BREAKER_STATE.CLOSED; } const state = JSON.parse(value); return state.type; } async updateState(key) { const value = await this.database.daiso_circuit_breaker_update_state(key, JSON.stringify(serializeBackoffSettingsEnum(this.backoff)), JSON.stringify(serializeCircuitBreakerPolicySettingsEnum(this.policy)), Date.now()); return JSON.parse(value); } async isolate(key) { await this.database.set(key, JSON.stringify({ type: CIRCUIT_BREAKER_STATE.ISOLATED, })); } async trackFailure(key) { await this.database.daiso_circuit_breaker_track_failure(key, JSON.stringify(serializeBackoffSettingsEnum(this.backoff)), JSON.stringify(serializeCircuitBreakerPolicySettingsEnum(this.policy)), Date.now()); } async trackSuccess(key) { await this.database.daiso_circuit_breaker_track_success(key, JSON.stringify(serializeBackoffSettingsEnum(this.backoff)), JSON.stringify(serializeCircuitBreakerPolicySettingsEnum(this.policy)), Date.now()); } async reset(key) { await this.database.del(key); } } //# sourceMappingURL=redis-circuit-breaker-adapter.js.map