@takentrade/takentrade-libs 2.0.8 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +87 -0
- package/README.md +112 -743
- package/dist/common/health/health.controller.js +0 -2
- package/dist/common/index.d.ts +0 -2
- package/dist/common/index.js +0 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/metrics/circuit-breaker-metrics.service.d.ts +61 -0
- package/dist/metrics/circuit-breaker-metrics.service.js +149 -0
- package/dist/metrics/index.d.ts +5 -0
- package/dist/metrics/index.js +21 -0
- package/dist/metrics/metrics-registry.d.ts +50 -0
- package/dist/metrics/metrics-registry.js +156 -0
- package/dist/metrics/metrics-updater.d.ts +32 -0
- package/dist/metrics/metrics-updater.js +102 -0
- package/dist/metrics/metrics.controller.d.ts +11 -0
- package/dist/metrics/metrics.controller.js +32 -0
- package/dist/metrics/metrics.interface.d.ts +106 -0
- package/dist/metrics/metrics.interface.js +35 -0
- package/dist/metrics/metrics.module.d.ts +11 -0
- package/dist/metrics/metrics.module.js +39 -0
- package/dist/metrics/metrics.service.d.ts +50 -0
- package/dist/metrics/metrics.service.js +165 -0
- package/dist/resilience/circuit-breaker-event-handler.d.ts +16 -0
- package/dist/resilience/circuit-breaker-event-handler.js +70 -0
- package/dist/resilience/circuit-breaker-factory.d.ts +19 -0
- package/dist/resilience/circuit-breaker-factory.js +51 -0
- package/dist/resilience/circuit-breaker-stats.service.d.ts +37 -0
- package/dist/resilience/circuit-breaker-stats.service.js +69 -0
- package/dist/resilience/circuit-breaker.interface.d.ts +134 -0
- package/dist/resilience/circuit-breaker.interface.js +31 -0
- package/dist/{common/circuit-breaker → resilience}/circuit-breaker.module.js +1 -0
- package/dist/resilience/circuit-breaker.service.d.ts +119 -0
- package/dist/resilience/circuit-breaker.service.js +234 -0
- package/dist/resilience/index.d.ts +3 -0
- package/dist/resilience/index.js +19 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/dto/pagination.js +0 -6
- package/package.json +5 -2
- package/dist/common/circuit-breaker/circuit-breaker.service.d.ts +0 -13
- package/dist/common/circuit-breaker/circuit-breaker.service.js +0 -120
- package/dist/common/circuit-breaker/circuit-breaker.types.d.ts +0 -19
- package/dist/common/circuit-breaker/circuit-breaker.types.js +0 -9
- /package/dist/{common/circuit-breaker → resilience}/circuit-breaker.module.d.ts +0 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import CircuitBreaker from 'opossum';
|
|
2
|
+
/**
|
|
3
|
+
* Circuit breaker state enum
|
|
4
|
+
*/
|
|
5
|
+
export declare enum CircuitState {
|
|
6
|
+
CLOSED = "closed",
|
|
7
|
+
OPEN = "open",
|
|
8
|
+
HALF_OPEN = "halfOpen"
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Circuit breaker options based on Opossum configuration
|
|
12
|
+
* @see https://nodeshift.dev/opossum/
|
|
13
|
+
*/
|
|
14
|
+
export interface CircuitBreakerOptions {
|
|
15
|
+
/**
|
|
16
|
+
* The time in milliseconds that action should be allowed to execute before timing out.
|
|
17
|
+
* @default 10000 (10 seconds)
|
|
18
|
+
*/
|
|
19
|
+
timeout?: number;
|
|
20
|
+
/**
|
|
21
|
+
* The number of times the circuit can fail before opening.
|
|
22
|
+
* @default 50
|
|
23
|
+
*/
|
|
24
|
+
errorThresholdPercentage?: number;
|
|
25
|
+
/**
|
|
26
|
+
* The time in milliseconds to wait before setting the breaker to halfOpen state.
|
|
27
|
+
* @default 30000 (30 seconds)
|
|
28
|
+
*/
|
|
29
|
+
resetTimeout?: number;
|
|
30
|
+
/**
|
|
31
|
+
* The rolling statistical window in milliseconds.
|
|
32
|
+
* @default 10000 (10 seconds)
|
|
33
|
+
*/
|
|
34
|
+
rollingCountTimeout?: number;
|
|
35
|
+
/**
|
|
36
|
+
* The number of buckets the rolling statistical window is divided into.
|
|
37
|
+
* @default 10
|
|
38
|
+
*/
|
|
39
|
+
rollingCountBuckets?: number;
|
|
40
|
+
/**
|
|
41
|
+
* The name of the circuit breaker (for logging and metrics).
|
|
42
|
+
*/
|
|
43
|
+
name?: string;
|
|
44
|
+
/**
|
|
45
|
+
* The capacity of the internal event bus.
|
|
46
|
+
* @default 100
|
|
47
|
+
*/
|
|
48
|
+
capacity?: number;
|
|
49
|
+
/**
|
|
50
|
+
* Whether to enable snapshots for metrics.
|
|
51
|
+
* @default false
|
|
52
|
+
*/
|
|
53
|
+
enableSnapshots?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Whether to allow warm up period (ignore errors initially).
|
|
56
|
+
* @default false
|
|
57
|
+
*/
|
|
58
|
+
allowWarmUp?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* The number of requests to allow during warm up.
|
|
61
|
+
* @default 0
|
|
62
|
+
*/
|
|
63
|
+
volumeThreshold?: number;
|
|
64
|
+
/**
|
|
65
|
+
* Custom error filter function to determine if an error should trip the circuit.
|
|
66
|
+
*/
|
|
67
|
+
errorFilter?: (error: any) => boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Whether to cache the result of successful calls.
|
|
70
|
+
* @default false
|
|
71
|
+
*/
|
|
72
|
+
cache?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Cache TTL in milliseconds.
|
|
75
|
+
* @default 0
|
|
76
|
+
*/
|
|
77
|
+
cacheTTL?: number;
|
|
78
|
+
/**
|
|
79
|
+
* Custom cache key generator function.
|
|
80
|
+
*/
|
|
81
|
+
cacheGetKey?: (...args: any[]) => string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Circuit breaker statistics
|
|
85
|
+
*/
|
|
86
|
+
export interface CircuitBreakerStats {
|
|
87
|
+
fires: number;
|
|
88
|
+
failures: number;
|
|
89
|
+
successes: number;
|
|
90
|
+
rejects: number;
|
|
91
|
+
timeouts: number;
|
|
92
|
+
cacheHits: number;
|
|
93
|
+
cacheMisses: number;
|
|
94
|
+
semaphoreRejections: number;
|
|
95
|
+
percentiles: {
|
|
96
|
+
[percentile: number]: number;
|
|
97
|
+
};
|
|
98
|
+
latencyMean: number;
|
|
99
|
+
latencyTimes: number[];
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Circuit breaker event types
|
|
103
|
+
*/
|
|
104
|
+
export declare enum CircuitBreakerEvent {
|
|
105
|
+
FIRE = "fire",
|
|
106
|
+
SUCCESS = "success",
|
|
107
|
+
FAILURE = "failure",
|
|
108
|
+
TIMEOUT = "timeout",
|
|
109
|
+
REJECT = "reject",
|
|
110
|
+
OPEN = "open",
|
|
111
|
+
CLOSE = "close",
|
|
112
|
+
HALF_OPEN = "halfOpen",
|
|
113
|
+
FALLBACK = "fallback",
|
|
114
|
+
SEMAPHORE_LOCKED = "semaphoreLocked",
|
|
115
|
+
HEALTH_CHECK_FAILED = "healthCheckFailed",
|
|
116
|
+
CACHE_HIT = "cacheHit",
|
|
117
|
+
CACHE_MISS = "cacheMiss"
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Circuit breaker instance wrapper
|
|
121
|
+
*/
|
|
122
|
+
export interface CircuitBreakerInstance<T = any, R = any> {
|
|
123
|
+
breaker: CircuitBreaker<T[], R>;
|
|
124
|
+
name: string;
|
|
125
|
+
options: CircuitBreakerOptions;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Fallback function type
|
|
129
|
+
*/
|
|
130
|
+
export type FallbackFunction<T = any> = (...args: any[]) => T | Promise<T>;
|
|
131
|
+
/**
|
|
132
|
+
* Health check function type
|
|
133
|
+
*/
|
|
134
|
+
export type HealthCheckFunction = () => Promise<boolean>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CircuitBreakerEvent = exports.CircuitState = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Circuit breaker state enum
|
|
6
|
+
*/
|
|
7
|
+
var CircuitState;
|
|
8
|
+
(function (CircuitState) {
|
|
9
|
+
CircuitState["CLOSED"] = "closed";
|
|
10
|
+
CircuitState["OPEN"] = "open";
|
|
11
|
+
CircuitState["HALF_OPEN"] = "halfOpen";
|
|
12
|
+
})(CircuitState || (exports.CircuitState = CircuitState = {}));
|
|
13
|
+
/**
|
|
14
|
+
* Circuit breaker event types
|
|
15
|
+
*/
|
|
16
|
+
var CircuitBreakerEvent;
|
|
17
|
+
(function (CircuitBreakerEvent) {
|
|
18
|
+
CircuitBreakerEvent["FIRE"] = "fire";
|
|
19
|
+
CircuitBreakerEvent["SUCCESS"] = "success";
|
|
20
|
+
CircuitBreakerEvent["FAILURE"] = "failure";
|
|
21
|
+
CircuitBreakerEvent["TIMEOUT"] = "timeout";
|
|
22
|
+
CircuitBreakerEvent["REJECT"] = "reject";
|
|
23
|
+
CircuitBreakerEvent["OPEN"] = "open";
|
|
24
|
+
CircuitBreakerEvent["CLOSE"] = "close";
|
|
25
|
+
CircuitBreakerEvent["HALF_OPEN"] = "halfOpen";
|
|
26
|
+
CircuitBreakerEvent["FALLBACK"] = "fallback";
|
|
27
|
+
CircuitBreakerEvent["SEMAPHORE_LOCKED"] = "semaphoreLocked";
|
|
28
|
+
CircuitBreakerEvent["HEALTH_CHECK_FAILED"] = "healthCheckFailed";
|
|
29
|
+
CircuitBreakerEvent["CACHE_HIT"] = "cacheHit";
|
|
30
|
+
CircuitBreakerEvent["CACHE_MISS"] = "cacheMiss";
|
|
31
|
+
})(CircuitBreakerEvent || (exports.CircuitBreakerEvent = CircuitBreakerEvent = {}));
|
|
@@ -13,6 +13,7 @@ let CircuitBreakerModule = class CircuitBreakerModule {
|
|
|
13
13
|
};
|
|
14
14
|
exports.CircuitBreakerModule = CircuitBreakerModule;
|
|
15
15
|
exports.CircuitBreakerModule = CircuitBreakerModule = __decorate([
|
|
16
|
+
(0, common_1.Global)(),
|
|
16
17
|
(0, common_1.Module)({
|
|
17
18
|
providers: [circuit_breaker_service_1.CircuitBreakerService],
|
|
18
19
|
exports: [circuit_breaker_service_1.CircuitBreakerService],
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { OnModuleDestroy } from '@nestjs/common';
|
|
2
|
+
import CircuitBreaker from 'opossum';
|
|
3
|
+
import { CircuitBreakerOptions, CircuitBreakerStats, CircuitState, FallbackFunction } from './circuit-breaker.interface';
|
|
4
|
+
export declare class CircuitBreakerService implements OnModuleDestroy {
|
|
5
|
+
private readonly logger;
|
|
6
|
+
private readonly breakers;
|
|
7
|
+
private readonly factory;
|
|
8
|
+
private readonly statsService;
|
|
9
|
+
/**
|
|
10
|
+
* Create a new circuit breaker instance
|
|
11
|
+
*
|
|
12
|
+
* @param name - Unique identifier for the circuit breaker
|
|
13
|
+
* @param action - The async function to be protected
|
|
14
|
+
* @param options - Circuit breaker configuration options
|
|
15
|
+
* @returns Circuit breaker instance
|
|
16
|
+
*/
|
|
17
|
+
createBreaker<T = any, R = any>(name: string, action: (...args: T[]) => Promise<R>, options?: CircuitBreakerOptions): CircuitBreaker<T[], R>;
|
|
18
|
+
/**
|
|
19
|
+
* Execute a protected function through the circuit breaker
|
|
20
|
+
*
|
|
21
|
+
* @param name - Circuit breaker name
|
|
22
|
+
* @param args - Arguments to pass to the protected function
|
|
23
|
+
* @returns Result of the protected function
|
|
24
|
+
*/
|
|
25
|
+
fire<T = any>(name: string, ...args: any[]): Promise<T>;
|
|
26
|
+
/**
|
|
27
|
+
* Set a fallback function for a circuit breaker
|
|
28
|
+
*
|
|
29
|
+
* @param name - Circuit breaker name
|
|
30
|
+
* @param fallback - Fallback function to execute when circuit is open
|
|
31
|
+
*/
|
|
32
|
+
setFallback<T = any>(name: string, fallback: FallbackFunction<T>): void;
|
|
33
|
+
/**
|
|
34
|
+
* Set a health check function for a circuit breaker
|
|
35
|
+
*
|
|
36
|
+
* @param name - Circuit breaker name
|
|
37
|
+
* @param healthCheck - Health check function
|
|
38
|
+
* @param interval - Health check interval in milliseconds (default: 5000)
|
|
39
|
+
*/
|
|
40
|
+
setHealthCheck(name: string, healthCheck: () => Promise<void>, interval?: number): void;
|
|
41
|
+
/**
|
|
42
|
+
* Note: Caching should be configured during circuit breaker creation via options.
|
|
43
|
+
* This is a limitation of the current Opossum version.
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* Clear the cache for a circuit breaker
|
|
47
|
+
*
|
|
48
|
+
* @param name - Circuit breaker name
|
|
49
|
+
*/
|
|
50
|
+
clearCache(name: string): void;
|
|
51
|
+
/**
|
|
52
|
+
* Get the current state of a circuit breaker
|
|
53
|
+
*
|
|
54
|
+
* @param name - Circuit breaker name
|
|
55
|
+
* @returns Current circuit state
|
|
56
|
+
*/
|
|
57
|
+
getState(name: string): CircuitState;
|
|
58
|
+
/**
|
|
59
|
+
* Check if a circuit breaker is open
|
|
60
|
+
*
|
|
61
|
+
* @param name - Circuit breaker name
|
|
62
|
+
* @returns True if circuit is open
|
|
63
|
+
*/
|
|
64
|
+
isOpen(name: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Get statistics for a circuit breaker
|
|
67
|
+
*
|
|
68
|
+
* @param name - Circuit breaker name
|
|
69
|
+
* @returns Circuit breaker statistics
|
|
70
|
+
*/
|
|
71
|
+
getStats(name: string): CircuitBreakerStats;
|
|
72
|
+
/**
|
|
73
|
+
* Get all circuit breaker statistics
|
|
74
|
+
*
|
|
75
|
+
* @returns Map of circuit breaker names to their statistics
|
|
76
|
+
*/
|
|
77
|
+
getAllStats(): Map<string, CircuitBreakerStats>;
|
|
78
|
+
/**
|
|
79
|
+
* Manually open a circuit breaker
|
|
80
|
+
*
|
|
81
|
+
* @param name - Circuit breaker name
|
|
82
|
+
*/
|
|
83
|
+
open(name: string): void;
|
|
84
|
+
/**
|
|
85
|
+
* Manually close a circuit breaker
|
|
86
|
+
*
|
|
87
|
+
* @param name - Circuit breaker name
|
|
88
|
+
*/
|
|
89
|
+
close(name: string): void;
|
|
90
|
+
/**
|
|
91
|
+
* Reset a circuit breaker (clear stats and close)
|
|
92
|
+
*
|
|
93
|
+
* @param name - Circuit breaker name
|
|
94
|
+
*/
|
|
95
|
+
reset(name: string): void;
|
|
96
|
+
/**
|
|
97
|
+
* Remove a circuit breaker instance
|
|
98
|
+
*
|
|
99
|
+
* @param name - Circuit breaker name
|
|
100
|
+
*/
|
|
101
|
+
remove(name: string): void;
|
|
102
|
+
/**
|
|
103
|
+
* Get all circuit breaker names
|
|
104
|
+
*
|
|
105
|
+
* @returns Array of circuit breaker names
|
|
106
|
+
*/
|
|
107
|
+
getBreakerNames(): string[];
|
|
108
|
+
/**
|
|
109
|
+
* Check if a circuit breaker exists
|
|
110
|
+
*
|
|
111
|
+
* @param name - Circuit breaker name
|
|
112
|
+
* @returns True if circuit breaker exists
|
|
113
|
+
*/
|
|
114
|
+
hasBreaker(name: string): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Cleanup on module destroy
|
|
117
|
+
*/
|
|
118
|
+
onModuleDestroy(): Promise<void>;
|
|
119
|
+
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var CircuitBreakerService_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.CircuitBreakerService = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const circuit_breaker_factory_1 = require("./circuit-breaker-factory");
|
|
13
|
+
const circuit_breaker_stats_service_1 = require("./circuit-breaker-stats.service");
|
|
14
|
+
let CircuitBreakerService = CircuitBreakerService_1 = class CircuitBreakerService {
|
|
15
|
+
logger = new common_1.Logger(CircuitBreakerService_1.name);
|
|
16
|
+
breakers = new Map();
|
|
17
|
+
factory = new circuit_breaker_factory_1.CircuitBreakerFactory();
|
|
18
|
+
statsService = new circuit_breaker_stats_service_1.CircuitBreakerStatsService();
|
|
19
|
+
/**
|
|
20
|
+
* Create a new circuit breaker instance
|
|
21
|
+
*
|
|
22
|
+
* @param name - Unique identifier for the circuit breaker
|
|
23
|
+
* @param action - The async function to be protected
|
|
24
|
+
* @param options - Circuit breaker configuration options
|
|
25
|
+
* @returns Circuit breaker instance
|
|
26
|
+
*/
|
|
27
|
+
createBreaker(name, action, options = {}) {
|
|
28
|
+
if (this.breakers.has(name)) {
|
|
29
|
+
this.logger.warn(`Circuit breaker '${name}' already exists. Returning existing instance.`);
|
|
30
|
+
return this.breakers.get(name).breaker;
|
|
31
|
+
}
|
|
32
|
+
const instance = this.factory.create(name, action, options);
|
|
33
|
+
this.breakers.set(name, instance);
|
|
34
|
+
return instance.breaker;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Execute a protected function through the circuit breaker
|
|
38
|
+
*
|
|
39
|
+
* @param name - Circuit breaker name
|
|
40
|
+
* @param args - Arguments to pass to the protected function
|
|
41
|
+
* @returns Result of the protected function
|
|
42
|
+
*/
|
|
43
|
+
async fire(name, ...args) {
|
|
44
|
+
const instance = this.breakers.get(name);
|
|
45
|
+
if (!instance) {
|
|
46
|
+
throw new Error(`Circuit breaker '${name}' not found. Create it first using createBreaker()`);
|
|
47
|
+
}
|
|
48
|
+
return instance.breaker.fire(...args);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Set a fallback function for a circuit breaker
|
|
52
|
+
*
|
|
53
|
+
* @param name - Circuit breaker name
|
|
54
|
+
* @param fallback - Fallback function to execute when circuit is open
|
|
55
|
+
*/
|
|
56
|
+
setFallback(name, fallback) {
|
|
57
|
+
const instance = this.breakers.get(name);
|
|
58
|
+
if (!instance) {
|
|
59
|
+
throw new Error(`Circuit breaker '${name}' not found`);
|
|
60
|
+
}
|
|
61
|
+
instance.breaker.fallback(fallback);
|
|
62
|
+
this.logger.log(`Fallback function set for circuit breaker '${name}'`);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Set a health check function for a circuit breaker
|
|
66
|
+
*
|
|
67
|
+
* @param name - Circuit breaker name
|
|
68
|
+
* @param healthCheck - Health check function
|
|
69
|
+
* @param interval - Health check interval in milliseconds (default: 5000)
|
|
70
|
+
*/
|
|
71
|
+
setHealthCheck(name, healthCheck, interval = 5000) {
|
|
72
|
+
const instance = this.breakers.get(name);
|
|
73
|
+
if (!instance) {
|
|
74
|
+
throw new Error(`Circuit breaker '${name}' not found`);
|
|
75
|
+
}
|
|
76
|
+
instance.breaker.healthCheck(healthCheck, interval);
|
|
77
|
+
this.logger.log(`Health check set for circuit breaker '${name}' with ${interval}ms interval`);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Note: Caching should be configured during circuit breaker creation via options.
|
|
81
|
+
* This is a limitation of the current Opossum version.
|
|
82
|
+
*/
|
|
83
|
+
/**
|
|
84
|
+
* Clear the cache for a circuit breaker
|
|
85
|
+
*
|
|
86
|
+
* @param name - Circuit breaker name
|
|
87
|
+
*/
|
|
88
|
+
clearCache(name) {
|
|
89
|
+
const instance = this.breakers.get(name);
|
|
90
|
+
if (!instance) {
|
|
91
|
+
throw new Error(`Circuit breaker '${name}' not found`);
|
|
92
|
+
}
|
|
93
|
+
instance.breaker.clearCache();
|
|
94
|
+
this.logger.debug(`Cache cleared for circuit breaker '${name}'`);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get the current state of a circuit breaker
|
|
98
|
+
*
|
|
99
|
+
* @param name - Circuit breaker name
|
|
100
|
+
* @returns Current circuit state
|
|
101
|
+
*/
|
|
102
|
+
getState(name) {
|
|
103
|
+
const instance = this.breakers.get(name);
|
|
104
|
+
if (!instance) {
|
|
105
|
+
throw new Error(`Circuit breaker '${name}' not found`);
|
|
106
|
+
}
|
|
107
|
+
return this.statsService.getState(instance.breaker);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Check if a circuit breaker is open
|
|
111
|
+
*
|
|
112
|
+
* @param name - Circuit breaker name
|
|
113
|
+
* @returns True if circuit is open
|
|
114
|
+
*/
|
|
115
|
+
isOpen(name) {
|
|
116
|
+
const instance = this.breakers.get(name);
|
|
117
|
+
if (!instance) {
|
|
118
|
+
throw new Error(`Circuit breaker '${name}' not found`);
|
|
119
|
+
}
|
|
120
|
+
return this.statsService.isOpen(instance.breaker);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get statistics for a circuit breaker
|
|
124
|
+
*
|
|
125
|
+
* @param name - Circuit breaker name
|
|
126
|
+
* @returns Circuit breaker statistics
|
|
127
|
+
*/
|
|
128
|
+
getStats(name) {
|
|
129
|
+
const instance = this.breakers.get(name);
|
|
130
|
+
if (!instance) {
|
|
131
|
+
throw new Error(`Circuit breaker '${name}' not found`);
|
|
132
|
+
}
|
|
133
|
+
return this.statsService.getStats(instance);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Get all circuit breaker statistics
|
|
137
|
+
*
|
|
138
|
+
* @returns Map of circuit breaker names to their statistics
|
|
139
|
+
*/
|
|
140
|
+
getAllStats() {
|
|
141
|
+
return this.statsService.getAllStats(this.breakers);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Manually open a circuit breaker
|
|
145
|
+
*
|
|
146
|
+
* @param name - Circuit breaker name
|
|
147
|
+
*/
|
|
148
|
+
open(name) {
|
|
149
|
+
const instance = this.breakers.get(name);
|
|
150
|
+
if (!instance) {
|
|
151
|
+
throw new Error(`Circuit breaker '${name}' not found`);
|
|
152
|
+
}
|
|
153
|
+
instance.breaker.open();
|
|
154
|
+
this.logger.warn(`Circuit breaker '${name}' manually opened`);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Manually close a circuit breaker
|
|
158
|
+
*
|
|
159
|
+
* @param name - Circuit breaker name
|
|
160
|
+
*/
|
|
161
|
+
close(name) {
|
|
162
|
+
const instance = this.breakers.get(name);
|
|
163
|
+
if (!instance) {
|
|
164
|
+
throw new Error(`Circuit breaker '${name}' not found`);
|
|
165
|
+
}
|
|
166
|
+
instance.breaker.close();
|
|
167
|
+
this.logger.log(`Circuit breaker '${name}' manually closed`);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Reset a circuit breaker (clear stats and close)
|
|
171
|
+
*
|
|
172
|
+
* @param name - Circuit breaker name
|
|
173
|
+
*/
|
|
174
|
+
reset(name) {
|
|
175
|
+
const instance = this.breakers.get(name);
|
|
176
|
+
if (!instance) {
|
|
177
|
+
throw new Error(`Circuit breaker '${name}' not found`);
|
|
178
|
+
}
|
|
179
|
+
instance.breaker.close();
|
|
180
|
+
this.logger.log(`Circuit breaker '${name}' reset`);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Remove a circuit breaker instance
|
|
184
|
+
*
|
|
185
|
+
* @param name - Circuit breaker name
|
|
186
|
+
*/
|
|
187
|
+
remove(name) {
|
|
188
|
+
const instance = this.breakers.get(name);
|
|
189
|
+
if (!instance) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
instance.breaker.shutdown();
|
|
193
|
+
this.breakers.delete(name);
|
|
194
|
+
this.logger.log(`Circuit breaker '${name}' removed`);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Get all circuit breaker names
|
|
198
|
+
*
|
|
199
|
+
* @returns Array of circuit breaker names
|
|
200
|
+
*/
|
|
201
|
+
getBreakerNames() {
|
|
202
|
+
return Array.from(this.breakers.keys());
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Check if a circuit breaker exists
|
|
206
|
+
*
|
|
207
|
+
* @param name - Circuit breaker name
|
|
208
|
+
* @returns True if circuit breaker exists
|
|
209
|
+
*/
|
|
210
|
+
hasBreaker(name) {
|
|
211
|
+
return this.breakers.has(name);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Cleanup on module destroy
|
|
215
|
+
*/
|
|
216
|
+
async onModuleDestroy() {
|
|
217
|
+
this.logger.log('Shutting down all circuit breakers...');
|
|
218
|
+
for (const [name, instance] of this.breakers.entries()) {
|
|
219
|
+
try {
|
|
220
|
+
instance.breaker.shutdown();
|
|
221
|
+
this.logger.log(`Circuit breaker '${name}' shut down successfully`);
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
this.logger.error(`Error shutting down circuit breaker '${name}':`, error);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
this.breakers.clear();
|
|
228
|
+
this.logger.log('All circuit breakers shut down');
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
exports.CircuitBreakerService = CircuitBreakerService;
|
|
232
|
+
exports.CircuitBreakerService = CircuitBreakerService = CircuitBreakerService_1 = __decorate([
|
|
233
|
+
(0, common_1.Injectable)()
|
|
234
|
+
], CircuitBreakerService);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./circuit-breaker.module"), exports);
|
|
18
|
+
__exportStar(require("./circuit-breaker.service"), exports);
|
|
19
|
+
__exportStar(require("./circuit-breaker.interface"), exports);
|