- Decorators and tools that can easily apply the Circuit Breaker pattern.
- Node version >= 16
- Depends on worker thread and BroadcastChannel.
- NPM
$ npm install node-circuit-breaker --save
- Yarn
$ yarn add node-circuit-breaker
- You may need additional
axios
,@nestjs/common
, andtypeorm
packages to use the Error Wrapper.
- Options
Member | Sub | Type | Required | Description |
---|---|---|---|---|
fallback |
Function string Object |
required | An error object to return or a function to run when CircuitBreaker state:Open
|
|
rules |
Array<CircuitBreakerRule > |
required | Rules for determining state:Open | |
exceptions |
Array<typeof Error > |
required | Exception list | |
times |
number | required | Number of exceptions within the period | |
inSeconds |
number | required | Period(seconds) for counting exceptions | |
fallbackForSeconds |
number | required | Period(seconds) to respond with fallback before Open -> HalfOpen | |
timeoutMilliSeconds |
number | If the execution of the method takes longer than the specified time (ms), ExecutionTimeoutError is generated internally. You can use ExecutionTimeoutError in CircuitBreaker rules. | ||
scope |
CircuitBreakerScope |
|
||
onCircuitOpen |
(circuit: Circuit) => Promise<boolean> | A callback called when state changes to Open. If false is returned, the state is not changed. | ||
onCircuitClose |
(circuit: Circuit) => Promise<boolean> | A callback called when state changes to Closed. If false is returned, the state is not changed. | ||
ignore |
(error: any, circuit: Circuit) => Promise<boolean> | A callback that is called when an error occurs. If true is returned, the error is ignored and the circuit is not affected. | ||
onError |
(error: any, circuit: Circuit) => Promise<void> | A callback that is called when an error occurs. |
CircuitBreakerManager.terminate()
- Terminate CircuitBreaker Worker. Circuit state change stops.
class Test {
@CircuitBreaker({
// If state:Open, execute test1Fallback(...) within the same instance.
fallback: 'test1Fallback',
rules: [
// TypeormQueryTimeoutError, RequestTimeoutException, GatewayTimeoutException
// If an error occurs 10 times within 60 seconds, state:Open is set and a fallback is performed.
{
exceptions: [TypeormQueryTimeoutError, RequestTimeoutException, GatewayTimeoutException],
times: 10,
inSeconds: 60
},
// BadGatewayException, TypeormConnectionFailedError, ServiceUnavailableException
// If an error occurs 30 times within 5 seconds, state:Open is set and fallback is performed.
{
exceptions: [BadGatewayException, TypeormConnectionFailedError, ServiceUnavailableException],
times: 30,
inSeconds: 5
}
],
// After state:Open, it becomes state:HalfOpen after 5 seconds, and some calls are performed normally.
// If an error occurs at this time, it changes back to state:Open, and then changes to state:HalfOpen again after 5 seconds.
// If a normal response is made in state:HalfOpen state, it becomes state:Closed state.
fallbackForSeconds: 5,
})
test1(arg: string) {
if (arg === 'error') throw new BadGatewayException();
return arg;
}
test1Fallback(arg: string) {
return 'fallback';
}
@CircuitBreaker({
scope: CircuitBreakerScope.INSTANCE,
fallback: TestFallback.test2,
// If the method takes more than 1000ms to execute, an ExecutionTimeoutError error is generated.
// ExecutionTimeoutError is not thrown, only passed inside the circuit breaker.
timeoutMilliSeconds: 1000,
rules: [
{ exceptions: [BadGatewayException], times: 10, inSeconds: 5 },
{ exceptions: [ExecutionTimeoutError], times: 3, inSeconds: 10 }
],
fallbackForSeconds: 3,
})
test2(arg: string) {
if (arg === 'error') throw new BadGatewayException();
return arg;
}
}
class TestFallback {
static test2(arg: string) {
return arg;
}
}
- Provides error wrappers for frequently used functions.
- The provided Error Wrapper and all kinds of Errors can be caught by
@CircuitBreaker({ rules[].exceptions[...] })
.
@CircuitBreaker({...})
IftimeoutMilliSeconds
is set,ExecutionTimeoutError
occurs if the execution time of the method is longer than the set time.
- Refines
QueryFailedError
iftypeorm
is installed. - If the SQL query fails, you can catch the error by identifying whether it is a connection issue or a timeout.
Source Error | Converted | Condition |
---|---|---|
QueryFailedError |
TypeormConnectionFailedError |
QueryFailedError.driverError contains connection |
QueryFailedError |
TypeormQueryTimeoutError |
QueryFailedError.driverError contains timeout |
- Axios returns an error in the form of
AxiosError
when an error occurs, so it is difficult to use in exception filter. - By converting
AxiosError
intoHttpException
form of Nestjs and using it as a rule of CircuitBreaker, detailed rule setting is possible. - Requires
axios
,@nestjs/common
packages. - Transform rules