@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
JavaScript
/**
* @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