@sentienguard/apm 1.0.4 → 1.0.6
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/package.json +1 -1
- package/src/aggregator.js +463 -463
- package/src/browser/aggregator.js +38 -50
- package/src/browser/instrumentation.js +16 -19
- package/src/browser/transport.js +22 -21
- package/src/browser.js +3 -2
- package/src/circuitBreaker.js +264 -254
- package/src/dependencies.js +231 -236
- package/src/index.js +209 -209
- package/src/instrumentation.js +208 -208
- package/src/normalizer.js +147 -147
- package/src/transport.js +215 -214
package/src/circuitBreaker.js
CHANGED
|
@@ -1,254 +1,264 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Circuit Breaker Module
|
|
3
|
-
*
|
|
4
|
-
* Provides circuit breaker functionality using Opossum library.
|
|
5
|
-
* Wraps operations (especially database calls) to prevent cascade failures.
|
|
6
|
-
*
|
|
7
|
-
* Circuit States:
|
|
8
|
-
* - CLOSED: Normal operation, requests pass through
|
|
9
|
-
* - OPEN: Circuit tripped due to failures, requests fail fast
|
|
10
|
-
* - HALF-OPEN: Testing if service recovered, limited requests allowed
|
|
11
|
-
*
|
|
12
|
-
* Usage:
|
|
13
|
-
* import { createBreaker, wrapMongoOperation } from './circuitBreaker.js';
|
|
14
|
-
*
|
|
15
|
-
* // Wrap an async operation
|
|
16
|
-
* const breaker = createBreaker(async () => await db.query(), { name: 'db-query' });
|
|
17
|
-
* const result = await breaker.fire();
|
|
18
|
-
*
|
|
19
|
-
* // Or use the MongoDB helper
|
|
20
|
-
* const findUsers = wrapMongoOperation('User.find', async () => User.find());
|
|
21
|
-
* const users = await findUsers();
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
import config, { debug, warn } from './config.js';
|
|
25
|
-
import { getAggregator } from './aggregator.js';
|
|
26
|
-
|
|
27
|
-
// Store active circuit breakers
|
|
28
|
-
const breakers = new Map();
|
|
29
|
-
|
|
30
|
-
// Check if opossum is available
|
|
31
|
-
let CircuitBreaker = null;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Initialize Opossum (lazy load)
|
|
35
|
-
*/
|
|
36
|
-
async function initOpossum() {
|
|
37
|
-
if (CircuitBreaker) return true;
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
const opossum = await import('opossum');
|
|
41
|
-
CircuitBreaker = opossum.default || opossum;
|
|
42
|
-
debug('Opossum circuit breaker loaded');
|
|
43
|
-
return true;
|
|
44
|
-
} catch (err) {
|
|
45
|
-
debug('Opossum not installed. Circuit breaker disabled. Install with: npm install opossum');
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Default circuit breaker options
|
|
52
|
-
*/
|
|
53
|
-
function getDefaultOptions() {
|
|
54
|
-
return {
|
|
55
|
-
timeout: config.circuitBreaker.timeout,
|
|
56
|
-
errorThresholdPercentage: config.circuitBreaker.errorThresholdPercentage,
|
|
57
|
-
resetTimeout: config.circuitBreaker.resetTimeout,
|
|
58
|
-
volumeThreshold: config.circuitBreaker.volumeThreshold
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Create a circuit breaker for an async operation
|
|
64
|
-
*
|
|
65
|
-
* @param {Function} asyncFn - The async function to wrap
|
|
66
|
-
* @param {Object} options - Circuit breaker options
|
|
67
|
-
* @param {string} options.name - Name for the circuit (used for metrics)
|
|
68
|
-
* @param {number} options.timeout - Timeout in ms
|
|
69
|
-
* @param {number} options.errorThresholdPercentage - Error threshold to trip
|
|
70
|
-
* @param {number} options.resetTimeout - Time before attempting recovery
|
|
71
|
-
* @param {Function} options.fallback - Fallback function when circuit is open
|
|
72
|
-
* @returns {Object} Circuit breaker instance or wrapped function if opossum unavailable
|
|
73
|
-
*/
|
|
74
|
-
export async function createBreaker(asyncFn, options = {}) {
|
|
75
|
-
if (!config.circuitBreaker.enabled) {
|
|
76
|
-
debug('Circuit breaker disabled, returning passthrough');
|
|
77
|
-
return createPassthrough(asyncFn);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const initialized = await initOpossum();
|
|
81
|
-
if (!initialized) {
|
|
82
|
-
return createPassthrough(asyncFn);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const name = options.name || 'unnamed';
|
|
86
|
-
const breakerOptions = {
|
|
87
|
-
...getDefaultOptions(),
|
|
88
|
-
...options,
|
|
89
|
-
name
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const breaker = new CircuitBreaker(asyncFn, breakerOptions);
|
|
93
|
-
const aggregator = getAggregator();
|
|
94
|
-
|
|
95
|
-
// Attach event listeners for metrics
|
|
96
|
-
breaker.on('open', () => {
|
|
97
|
-
aggregator.recordCircuitState(name, 'open');
|
|
98
|
-
warn(`Circuit breaker OPEN: ${name}`);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
breaker.on('halfOpen', () => {
|
|
102
|
-
aggregator.recordCircuitState(name, 'halfOpen');
|
|
103
|
-
debug(`Circuit breaker HALF-OPEN: ${name}`);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
breaker.on('close', () => {
|
|
107
|
-
aggregator.recordCircuitState(name, 'close');
|
|
108
|
-
debug(`Circuit breaker CLOSED: ${name}`);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
breaker.on('fallback', (result) => {
|
|
112
|
-
debug(`Circuit breaker fallback executed: ${name}`);
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
breaker.on('timeout', () => {
|
|
116
|
-
debug(`Circuit breaker timeout: ${name}`);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
breaker.on('reject', () => {
|
|
120
|
-
debug(`Circuit breaker rejected (circuit open): ${name}`);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
// Register fallback if provided
|
|
124
|
-
if (options.fallback) {
|
|
125
|
-
breaker.fallback(options.fallback);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Store reference
|
|
129
|
-
breakers.set(name, breaker);
|
|
130
|
-
|
|
131
|
-
return breaker;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Create a passthrough wrapper when circuit breaker is disabled
|
|
136
|
-
*/
|
|
137
|
-
function createPassthrough(asyncFn) {
|
|
138
|
-
return {
|
|
139
|
-
fire: (...args) => asyncFn(...args),
|
|
140
|
-
fallback: () => {},
|
|
141
|
-
on: () => {},
|
|
142
|
-
isOpen: () => false,
|
|
143
|
-
isClosed: () => true,
|
|
144
|
-
stats: { fires: 0, failures: 0, successes: 0 }
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Create a circuit breaker specifically for MongoDB operations
|
|
150
|
-
*
|
|
151
|
-
* @param {string} operationName - Name of the operation (e.g., 'User.find')
|
|
152
|
-
* @param {Function} mongoOperation - The MongoDB operation function
|
|
153
|
-
* @param {Object} options - Additional options
|
|
154
|
-
* @returns {Function} Wrapped function that uses circuit breaker
|
|
155
|
-
*/
|
|
156
|
-
export async function wrapMongoOperation(operationName, mongoOperation, options = {}) {
|
|
157
|
-
const breaker = await createBreaker(mongoOperation, {
|
|
158
|
-
name: `mongodb:${operationName}`,
|
|
159
|
-
// MongoDB-specific defaults
|
|
160
|
-
timeout: options.timeout || config.circuitBreaker.timeout,
|
|
161
|
-
errorThresholdPercentage: options.errorThresholdPercentage || 50,
|
|
162
|
-
resetTimeout: options.resetTimeout || 30000,
|
|
163
|
-
...options
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
// Return a function that fires the breaker
|
|
167
|
-
return async function wrappedOperation(...args) {
|
|
168
|
-
return breaker.fire(...args);
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Get a registered circuit breaker by name
|
|
174
|
-
*
|
|
175
|
-
* @param {string} name - Circuit breaker name
|
|
176
|
-
* @returns {Object|null} Circuit breaker instance or null
|
|
177
|
-
*/
|
|
178
|
-
export function getBreaker(name) {
|
|
179
|
-
return breakers.get(name) || null;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Get all registered circuit breakers
|
|
184
|
-
*
|
|
185
|
-
* @returns {Map} Map of circuit breaker instances
|
|
186
|
-
*/
|
|
187
|
-
export function getAllBreakers() {
|
|
188
|
-
return new Map(breakers);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Get circuit breaker statistics
|
|
193
|
-
*
|
|
194
|
-
* @param {string} name - Circuit breaker name (optional, returns all if not provided)
|
|
195
|
-
* @returns {Object} Statistics object
|
|
196
|
-
*/
|
|
197
|
-
export function getBreakerStats(name) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
export
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Circuit Breaker Module
|
|
3
|
+
*
|
|
4
|
+
* Provides circuit breaker functionality using Opossum library.
|
|
5
|
+
* Wraps operations (especially database calls) to prevent cascade failures.
|
|
6
|
+
*
|
|
7
|
+
* Circuit States:
|
|
8
|
+
* - CLOSED: Normal operation, requests pass through
|
|
9
|
+
* - OPEN: Circuit tripped due to failures, requests fail fast
|
|
10
|
+
* - HALF-OPEN: Testing if service recovered, limited requests allowed
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* import { createBreaker, wrapMongoOperation } from './circuitBreaker.js';
|
|
14
|
+
*
|
|
15
|
+
* // Wrap an async operation
|
|
16
|
+
* const breaker = createBreaker(async () => await db.query(), { name: 'db-query' });
|
|
17
|
+
* const result = await breaker.fire();
|
|
18
|
+
*
|
|
19
|
+
* // Or use the MongoDB helper
|
|
20
|
+
* const findUsers = wrapMongoOperation('User.find', async () => User.find());
|
|
21
|
+
* const users = await findUsers();
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import config, { debug, warn } from './config.js';
|
|
25
|
+
import { getAggregator } from './aggregator.js';
|
|
26
|
+
|
|
27
|
+
// Store active circuit breakers
|
|
28
|
+
const breakers = new Map();
|
|
29
|
+
|
|
30
|
+
// Check if opossum is available
|
|
31
|
+
let CircuitBreaker = null;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Initialize Opossum (lazy load)
|
|
35
|
+
*/
|
|
36
|
+
async function initOpossum() {
|
|
37
|
+
if (CircuitBreaker) return true;
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
const opossum = await import('opossum');
|
|
41
|
+
CircuitBreaker = opossum.default || opossum;
|
|
42
|
+
debug('Opossum circuit breaker loaded');
|
|
43
|
+
return true;
|
|
44
|
+
} catch (err) {
|
|
45
|
+
debug('Opossum not installed. Circuit breaker disabled. Install with: npm install opossum');
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Default circuit breaker options
|
|
52
|
+
*/
|
|
53
|
+
function getDefaultOptions() {
|
|
54
|
+
return {
|
|
55
|
+
timeout: config.circuitBreaker.timeout,
|
|
56
|
+
errorThresholdPercentage: config.circuitBreaker.errorThresholdPercentage,
|
|
57
|
+
resetTimeout: config.circuitBreaker.resetTimeout,
|
|
58
|
+
volumeThreshold: config.circuitBreaker.volumeThreshold
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Create a circuit breaker for an async operation
|
|
64
|
+
*
|
|
65
|
+
* @param {Function} asyncFn - The async function to wrap
|
|
66
|
+
* @param {Object} options - Circuit breaker options
|
|
67
|
+
* @param {string} options.name - Name for the circuit (used for metrics)
|
|
68
|
+
* @param {number} options.timeout - Timeout in ms
|
|
69
|
+
* @param {number} options.errorThresholdPercentage - Error threshold to trip
|
|
70
|
+
* @param {number} options.resetTimeout - Time before attempting recovery
|
|
71
|
+
* @param {Function} options.fallback - Fallback function when circuit is open
|
|
72
|
+
* @returns {Object} Circuit breaker instance or wrapped function if opossum unavailable
|
|
73
|
+
*/
|
|
74
|
+
export async function createBreaker(asyncFn, options = {}) {
|
|
75
|
+
if (!config.circuitBreaker.enabled) {
|
|
76
|
+
debug('Circuit breaker disabled, returning passthrough');
|
|
77
|
+
return createPassthrough(asyncFn);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const initialized = await initOpossum();
|
|
81
|
+
if (!initialized) {
|
|
82
|
+
return createPassthrough(asyncFn);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const name = options.name || 'unnamed';
|
|
86
|
+
const breakerOptions = {
|
|
87
|
+
...getDefaultOptions(),
|
|
88
|
+
...options,
|
|
89
|
+
name
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const breaker = new CircuitBreaker(asyncFn, breakerOptions);
|
|
93
|
+
const aggregator = getAggregator();
|
|
94
|
+
|
|
95
|
+
// Attach event listeners for metrics
|
|
96
|
+
breaker.on('open', () => {
|
|
97
|
+
aggregator.recordCircuitState(name, 'open');
|
|
98
|
+
warn(`Circuit breaker OPEN: ${name}`);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
breaker.on('halfOpen', () => {
|
|
102
|
+
aggregator.recordCircuitState(name, 'halfOpen');
|
|
103
|
+
debug(`Circuit breaker HALF-OPEN: ${name}`);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
breaker.on('close', () => {
|
|
107
|
+
aggregator.recordCircuitState(name, 'close');
|
|
108
|
+
debug(`Circuit breaker CLOSED: ${name}`);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
breaker.on('fallback', (result) => {
|
|
112
|
+
debug(`Circuit breaker fallback executed: ${name}`);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
breaker.on('timeout', () => {
|
|
116
|
+
debug(`Circuit breaker timeout: ${name}`);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
breaker.on('reject', () => {
|
|
120
|
+
debug(`Circuit breaker rejected (circuit open): ${name}`);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Register fallback if provided
|
|
124
|
+
if (options.fallback) {
|
|
125
|
+
breaker.fallback(options.fallback);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Store reference
|
|
129
|
+
breakers.set(name, breaker);
|
|
130
|
+
|
|
131
|
+
return breaker;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Create a passthrough wrapper when circuit breaker is disabled
|
|
136
|
+
*/
|
|
137
|
+
function createPassthrough(asyncFn) {
|
|
138
|
+
return {
|
|
139
|
+
fire: (...args) => asyncFn(...args),
|
|
140
|
+
fallback: () => {},
|
|
141
|
+
on: () => {},
|
|
142
|
+
isOpen: () => false,
|
|
143
|
+
isClosed: () => true,
|
|
144
|
+
stats: { fires: 0, failures: 0, successes: 0 }
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Create a circuit breaker specifically for MongoDB operations
|
|
150
|
+
*
|
|
151
|
+
* @param {string} operationName - Name of the operation (e.g., 'User.find')
|
|
152
|
+
* @param {Function} mongoOperation - The MongoDB operation function
|
|
153
|
+
* @param {Object} options - Additional options
|
|
154
|
+
* @returns {Function} Wrapped function that uses circuit breaker
|
|
155
|
+
*/
|
|
156
|
+
export async function wrapMongoOperation(operationName, mongoOperation, options = {}) {
|
|
157
|
+
const breaker = await createBreaker(mongoOperation, {
|
|
158
|
+
name: `mongodb:${operationName}`,
|
|
159
|
+
// MongoDB-specific defaults
|
|
160
|
+
timeout: options.timeout || config.circuitBreaker.timeout,
|
|
161
|
+
errorThresholdPercentage: options.errorThresholdPercentage || 50,
|
|
162
|
+
resetTimeout: options.resetTimeout || 30000,
|
|
163
|
+
...options
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Return a function that fires the breaker
|
|
167
|
+
return async function wrappedOperation(...args) {
|
|
168
|
+
return breaker.fire(...args);
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get a registered circuit breaker by name
|
|
174
|
+
*
|
|
175
|
+
* @param {string} name - Circuit breaker name
|
|
176
|
+
* @returns {Object|null} Circuit breaker instance or null
|
|
177
|
+
*/
|
|
178
|
+
export function getBreaker(name) {
|
|
179
|
+
return breakers.get(name) || null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Get all registered circuit breakers
|
|
184
|
+
*
|
|
185
|
+
* @returns {Map} Map of circuit breaker instances
|
|
186
|
+
*/
|
|
187
|
+
export function getAllBreakers() {
|
|
188
|
+
return new Map(breakers);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Get circuit breaker statistics
|
|
193
|
+
*
|
|
194
|
+
* @param {string} name - Circuit breaker name (optional, returns all if not provided)
|
|
195
|
+
* @returns {Object} Statistics object
|
|
196
|
+
*/
|
|
197
|
+
export function getBreakerStats(name) {
|
|
198
|
+
const getState = (breaker) => {
|
|
199
|
+
if (breaker.opened) {
|
|
200
|
+
return 'open';
|
|
201
|
+
}
|
|
202
|
+
if (breaker.halfOpen) {
|
|
203
|
+
return 'halfOpen';
|
|
204
|
+
}
|
|
205
|
+
return 'closed';
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
if (name) {
|
|
209
|
+
const breaker = breakers.get(name);
|
|
210
|
+
if (!breaker) return null;
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
name,
|
|
214
|
+
state: getState(breaker),
|
|
215
|
+
stats: breaker.stats
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Return stats for all breakers
|
|
220
|
+
const allStats = {};
|
|
221
|
+
for (const [breakerName, breaker] of breakers) {
|
|
222
|
+
allStats[breakerName] = {
|
|
223
|
+
state: getState(breaker),
|
|
224
|
+
stats: breaker.stats
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
return allStats;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Reset a circuit breaker (close it)
|
|
232
|
+
*
|
|
233
|
+
* @param {string} name - Circuit breaker name
|
|
234
|
+
*/
|
|
235
|
+
export function resetBreaker(name) {
|
|
236
|
+
const breaker = breakers.get(name);
|
|
237
|
+
if (breaker && typeof breaker.close === 'function') {
|
|
238
|
+
breaker.close();
|
|
239
|
+
debug(`Circuit breaker reset: ${name}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Shutdown all circuit breakers
|
|
245
|
+
*/
|
|
246
|
+
export function shutdownBreakers() {
|
|
247
|
+
for (const [ breaker] of breakers) {
|
|
248
|
+
if (typeof breaker.shutdown === 'function') {
|
|
249
|
+
breaker.shutdown();
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
breakers.clear();
|
|
253
|
+
debug('All circuit breakers shutdown');
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export default {
|
|
257
|
+
createBreaker,
|
|
258
|
+
wrapMongoOperation,
|
|
259
|
+
getBreaker,
|
|
260
|
+
getAllBreakers,
|
|
261
|
+
getBreakerStats,
|
|
262
|
+
resetBreaker,
|
|
263
|
+
shutdownBreakers
|
|
264
|
+
};
|