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.

138 lines 6.31 kB
/** * @module CircuitBreaker */ import { CIRCUIT_BREAKER_TRIGGER, } from "../../../../circuit-breaker/contracts/_module.js"; import { CircuitBreakerSerdeTransformer } from "../../../../circuit-breaker/implementations/derivables/circuit-breaker-provider/circuit-breaker-serde-transformer.js"; import { CircuitBreaker } from "../../../../circuit-breaker/implementations/derivables/circuit-breaker-provider/circuit-breaker.js"; import {} from "../../../../event-bus/contracts/_module.js"; import { NoOpEventBusAdapter } from "../../../../event-bus/implementations/adapters/_module.js"; import { EventBus } from "../../../../event-bus/implementations/derivables/_module.js"; import { Namespace } from "../../../../namespace/_module.js"; import {} from "../../../../serde/contracts/_module.js"; import { NoOpSerdeAdapter } from "../../../../serde/implementations/adapters/_module.js"; import { Serde } from "../../../../serde/implementations/derivables/serde.js"; import {} from "../../../../task/contracts/_module.js"; import {} from "../../../../time-span/contracts/_module.js"; import { TimeSpan } from "../../../../time-span/implementations/_module.js"; import { CORE, resolveOneOrMore, } from "../../../../utilities/_module.js"; /** * * IMPORT_PATH: `"@daiso-tech/core/circuit-breaker"` * @group Derivables */ export const DEFAULT_CIRCUIT_BREAKER_PROVIDER_NAMESPACE = new Namespace("@circuit-breaker"); /** * `CircuitBreakerProvider` class can be derived from any {@link ICircuitBreakerAdapter | `ICircuitBreakerAdapter`}. * * Note the {@link ICircuitBreaker | `ICircuitBreaker`} instances created by the `CircuitBreakerProvider` class are serializable and deserializable, * allowing them to be seamlessly transferred across different servers, processes, and databases. * This can be done directly using {@link ISerderRegister | `ISerderRegister`} or indirectly through components that rely on {@link ISerderRegister | `ISerderRegister`} internally. * * IMPORT_PATH: `"@daiso-tech/core/circuit-breaker"` * @group Derivables */ export class CircuitBreakerProvider { namespace; eventBus; adapter; defaultSlowCallTime; defaultTrigger; defaultErrorPolicy; serde; serdeTransformerName; enableAsyncTracking; /** * @example * ```ts * import { KyselyCircuitBreakerStorageAdapter } from "@daiso-tech/core/circuit-breaker/kysely-circuit-breaker-storage-adapter"; * import { DatabaseCircuitBreakerAdapter } from "@daiso-tech/core/circuit-breaker/database-circuit-breaker-adapter"; * import { Serde } from "@daiso-tech/core/serde"; * import { SuperJsonSerdeAdapter } from "@daiso-tech/core/serde/super-json-serde-adapter" * import Sqlite from "better-sqlite3"; * import { Kysely, SqliteDialect } from "kysely"; * * const serde = new Serde(new SuperJsonSerdeAdapter()); * const circuitBreakerStorageAdapter = new KyselyCircuitBreakerStorageAdapter({ * kysely: new Kysely({ * dialect: new SqliteDialect({ * database: new Sqlite("local.db"), * }), * }), * serde * }); * // You need initialize the adapter once before using it. * await circuitBreakerStorageAdapter.init(); * * const circuitBreakerAdapter = new DatabaseCircuitBreakerAdapter({ * adapter: circuitBreakerStorageAdapter * }); * * const circuitBreakerProvider = new CircuitBreakerProvider({ * adapter: circuitBreakerAdapter * }) * ``` */ constructor(settings) { const { enableAsyncTracking = true, namespace = DEFAULT_CIRCUIT_BREAKER_PROVIDER_NAMESPACE, eventBus = new EventBus({ adapter: new NoOpEventBusAdapter(), }), adapter, defaultSlowCallTime = TimeSpan.fromSeconds(10), defaultTrigger = CIRCUIT_BREAKER_TRIGGER.BOTH, defaultErrorPolicy = () => true, serde = new Serde(new NoOpSerdeAdapter()), serdeTransformerName = "", } = settings; this.enableAsyncTracking = enableAsyncTracking; this.namespace = namespace; this.eventBus = eventBus; this.adapter = adapter; this.defaultSlowCallTime = TimeSpan.fromTimeSpan(defaultSlowCallTime); this.defaultTrigger = defaultTrigger; this.defaultErrorPolicy = defaultErrorPolicy; this.serde = serde; this.serdeTransformerName = serdeTransformerName; this.registerToSerde(); } registerToSerde() { const transformer = new CircuitBreakerSerdeTransformer({ enableAsyncTracking: this.enableAsyncTracking, adapter: this.adapter, slowCallTime: this.defaultSlowCallTime, errorPolicy: this.defaultErrorPolicy, trigger: this.defaultTrigger, eventBus: this.eventBus, namespace: this.namespace, serdeTransformerName: this.serdeTransformerName, }); for (const serde of resolveOneOrMore(this.serde)) { serde.registerCustom(transformer, CORE); } } addListener(eventName, listener) { return this.eventBus.addListener(eventName, listener); } removeListener(eventName, listener) { return this.eventBus.removeListener(eventName, listener); } listenOnce(eventName, listener) { return this.eventBus.listenOnce(eventName, listener); } asTask(eventName) { return this.eventBus.asTask(eventName); } subscribeOnce(eventName, listener) { return this.eventBus.subscribeOnce(eventName, listener); } subscribe(eventName, listener) { return this.eventBus.subscribe(eventName, listener); } create(key, settings = {}) { const { errorPolicy = this.defaultErrorPolicy, trigger = this.defaultTrigger, slowCallTime = this.defaultSlowCallTime, } = settings; return new CircuitBreaker({ enableAsyncTracking: this.enableAsyncTracking, eventDispatcher: this.eventBus, adapter: this.adapter, key: this.namespace.create(key), slowCallTime: TimeSpan.fromTimeSpan(slowCallTime), errorPolicy, trigger, serdeTransformerName: this.serdeTransformerName, namespace: this.namespace, }); } } //# sourceMappingURL=circuit-breaker-provider.js.map