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.

132 lines (126 loc) 5.49 kB
/** * @module CircuitBreaker */ import {} from "ioredis"; import { BACKOFFS, resolveBackoffSettingsEnum, serializeBackoffSettingsEnum, } from "../../../../backoff-policies/implementations/_module.js"; import { CIRCUIT_BREAKER_STATE, } from "../../../../circuit-breaker/contracts/_module.js"; import {} from "../../../../circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/internal-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 {} from "../../../../execution-context/contracts/_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, backoffPolicy = { type: BACKOFFS.EXPONENTIAL, }, circuitBreakerPolicy = { type: BREAKER_POLICIES.CONSECUTIVE, }, } = settings; this.database = database; this.backoff = resolveBackoffSettingsEnum(backoffPolicy); this.policy = resolveCircuitBreakerPolicySettings(circuitBreakerPolicy); 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(_context, 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(_context, 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(_context, key) { await this.database.set(key, JSON.stringify({ type: CIRCUIT_BREAKER_STATE.ISOLATED, })); } async trackFailure(_context, key) { await this.database.daiso_circuit_breaker_track_failure(key, JSON.stringify(serializeBackoffSettingsEnum(this.backoff)), JSON.stringify(serializeCircuitBreakerPolicySettingsEnum(this.policy)), Date.now()); } async trackSuccess(_context, key) { await this.database.daiso_circuit_breaker_track_success(key, JSON.stringify(serializeBackoffSettingsEnum(this.backoff)), JSON.stringify(serializeCircuitBreakerPolicySettingsEnum(this.policy)), Date.now()); } async reset(_context, key) { await this.database.del(key); } } //# sourceMappingURL=redis-circuit-breaker-adapter.js.map