diff --git a/README.md b/README.md index c70715a6..f718469a 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ a network operation, or disk read, for example. Wrap those functions up in a `CircuitBreaker` and you have control over your destiny. ```javascript -const circuitBreaker = require('opossum'); +const CircuitBreaker = require('opossum'); function asyncFunctionThatCouldFail (x, y) { return new Promise((resolve, reject) => { @@ -46,7 +46,7 @@ const options = { errorThresholdPercentage: 50, // When 50% of requests fail, trip the circuit resetTimeout: 30000 // After 30 seconds, try again. }; -const breaker = circuitBreaker(asyncFunctionThatCouldFail, options); +const breaker = new CircuitBreaker(asyncFunctionThatCouldFail, options); breaker.fire(params) .then(console.log) @@ -60,7 +60,7 @@ event of failure. To take some action when the fallback is performed, listen for the `fallback` event. ```javascript -const breaker = circuitBreaker(asyncFunctionThatCouldFail, options); +const breaker = new CircuitBreaker(asyncFunctionThatCouldFail, options); // if asyncFunctionThatCouldFail starts to fail, firing the breaker // will trigger our fallback function breaker.fallback(() => 'Sorry, out of service right now'); @@ -124,7 +124,7 @@ server.route({ } }); ``` -In the browser's global scope will be a `circuitBreaker` function. Use it +In the browser's global scope will be a `CircuitBreaker` constructor. Use it to create circuit breakers, guarding against network failures in your REST API calls. @@ -137,7 +137,7 @@ const circuitBreakerOptions = { resetTimeout: 5000 }; -const circuit = circuitBreaker(() => $.get(route), circuitBreakerOptions); +const circuit = new CircuitBreaker(() => $.get(route), circuitBreakerOptions); circuit.fallback(() => `${route} unavailable right now. Try later.`)); circuit.on('success', (result) => $(element).append(JSON.stringify(result)})); @@ -167,7 +167,7 @@ Here are the events you can listen for. Handling events gives a greater level of control over your application behavior. ```js -const circuit = circuitBreaker(() => $.get(route), circuitBreakerOptions); +const circuit = new CircuitBreaker(() => $.get(route), circuitBreakerOptions); circuit.fallback(() => ({ body: `${route} unavailable right now. Try later.` })); @@ -211,10 +211,10 @@ Node core utility function `util.promisify()` . ```javascript const fs = require('fs'); const { promisify } = require('util'); -const circuitBreaker = require('opossum'); +const CircuitBreaker = require('opossum'); const readFile = promisify(fs.readFile); -const breaker = circuitBreaker(readFile, options); +const breaker = new CircuitBreaker(readFile, options); breaker.fire('./package.json', 'utf-8') .then(console.log) @@ -225,7 +225,7 @@ And just for fun, your circuit doesn't even really have to be a function. Not sure when you'd use this - but you could if you wanted to. ```javascript -const breaker = circuitBreaker('foo', options); +const breaker = new CircuitBreaker('foo', options); breaker.fire() .then(console.log) // logs 'foo' diff --git a/docs/index.html b/docs/index.html index f2de69ae..124e4c01 100644 --- a/docs/index.html +++ b/docs/index.html @@ -35,26 +35,6 @@
Let's say you've got an API that depends on something that might fail -
a network operation, or disk read, for example. Wrap those functions up in a
CircuitBreaker
and you have control over your destiny.
const circuitBreaker = require('opossum');
+const CircuitBreaker = require('opossum');
function asyncFunctionThatCouldFail (x, y) {
return new Promise((resolve, reject) => {
@@ -479,7 +459,7 @@ Usage
errorThresholdPercentage: 50, // When 50% of requests fail, trip the circuit
resetTimeout: 30000 // After 30 seconds, try again.
};
-const breaker = circuitBreaker(asyncFunctionThatCouldFail, options);
+const breaker = new CircuitBreaker(asyncFunctionThatCouldFail, options);
breaker.fire(params)
.then(console.log)
@@ -488,7 +468,7 @@ Fallback
You can also provide a fallback function that will be executed in the
event of failure. To take some action when the fallback is performed,
listen for the fallback
event.
-const breaker = circuitBreaker(asyncFunctionThatCouldFail, options);
+const breaker = new CircuitBreaker(asyncFunctionThatCouldFail, options);
// if asyncFunctionThatCouldFail starts to fail, firing the breaker
// will trigger our fallback function
breaker.fallback(() => 'Sorry, out of service right now');
@@ -655,328 +635,6 @@ Troubleshooting
-
-
-
-
-
-
- factory
-
-
-
-
-
-
- Creates a CircuitBreaker instance capable of executing action
.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.timeout Number
-
- The time in milliseconds that action should
-be allowed to execute before timing out. Default 10000 (10 seconds)
-
-
-
-
-
-
- options.maxFailures Number
-
- (Deprecated) The number of times the
-circuit can fail before opening. Default 10.
-
-
-
-
-
-
- options.resetTimeout Number
-
- The time in milliseconds to wait before
-setting the breaker to
-halfOpen
- state, and trying the action again.
-Default: 30000 (30 seconds)
-
-
-
-
-
-
- options.rollingCountTimeout Number
-
- Sets the duration of the
-statistical rolling window, in milliseconds. This is how long Opossum keeps
-metrics for the circuit breaker to use and for publishing. Default: 10000
-
-
-
-
-
-
- options.rollingCountBuckets Number
-
- Sets the number of buckets the
-rolling statistical window is divided into. So, if
-options.rollingCountTimeout is 10000, and options.rollingCountBuckets is 10,
-then the statistical window will be 1000 1 second snapshots in the
-statistical window. Default: 10
-
-
-
-
-
-
- options.name String
-
- the circuit name to use when reporting stats.
-Default: the name of the function this circuit controls.
-
-
-
-
-
-
- options.rollingPercentilesEnabled boolean
-
- This property indicates
-whether execution latencies should be tracked and calculated as percentiles.
-If they are disabled, all summary statistics (mean, percentiles) are
-returned as -1. Default: false
-
-
-
-
-
-
- options.capacity Number
-
- the number of concurrent requests allowed.
-If the number currently executing function calls is equal to
-options.capacity, further calls to
-fire()
- are rejected until at least one
-of the current requests completes. Default:
-Number.MAX_SAFE_INTEGER
-.
-
-
-
-
-
-
- options.errorThresholdPercentage Number
-
- the error percentage at
-which to open the circuit and start short-circuiting requests to fallback.
-Default: 50
-
-
-
-
-
-
- options.enabled boolean
-
- whether this circuit is enabled upon
-construction. Default: true
-
-
-
-
-
-
- options.allowWarmUp boolean
-
- determines whether to allow failures
-without opening the circuit during a brief warmup period (this is the
-
-rollingCountDuration
- property). Default: false
-allow before enabling the circuit. This can help in situations where no
-matter what your
-errorThresholdPercentage
- is, if the first execution
-times out or fails, the circuit immediately opens. Default: 0
-
-
-
-
-
-
- options.volumeThreshold Number
-
- the minimum number of requests within
-the rolling statistical window that must exist before the circuit breaker
-can open. This is similar to
-options.allowWarmUp
- in that no matter how many
-failures there are, if the number of requests within the statistical window
-does not exceed this threshold, the circuit will remain closed. Default: 0
-
-
-
-
-
-
- options.errorFilter Function
-
- an optional function that will be
-called when the circuit's function fails (returns a rejected Promise). If
-this function returns truthy, the circuit's failure statistics will not be
-incremented. This is useful, for example, when you don't want HTTP 404 to
-trip the circuit, but still want to handle it as a failure case.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- CircuitBreaker
:
- a newly created
-CircuitBreaker
- instance
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- factory.circuits
-
-
-
-
-
-
- Get an Iterator
object containing all
-circuits that have been created but not subsequently shut down.
-
- factory.circuits(): Iterator
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Iterator
:
- an
-
-Iterator
-
- of all available circuits
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/opossum.md b/docs/opossum.md
index 6dbb4f91..a6b46dcd 100644
--- a/docs/opossum.md
+++ b/docs/opossum.md
@@ -2,172 +2,105 @@
### Table of Contents
-- [factory][1]
+- [CircuitBreaker][1]
- [Parameters][2]
-- [factory.circuits][3]
-- [CircuitBreaker][4]
- - [Parameters][5]
- - [close][6]
- - [open][7]
- - [shutdown][8]
- - [isShutdown][9]
- - [name][10]
- - [group][11]
- - [pendingClose][12]
- - [closed][13]
- - [opened][14]
- - [halfOpen][15]
- - [status][16]
- - [stats][17]
- - [enabled][18]
- - [warmUp][19]
- - [volumeThreshold][20]
- - [fallback][21]
- - [Parameters][22]
- - [fire][23]
- - [clearCache][24]
- - [healthCheck][25]
- - [Parameters][26]
- - [enable][27]
- - [disable][28]
- - [circuits][29]
-- [CircuitBreaker#halfOpen][30]
-- [CircuitBreaker#close][31]
-- [CircuitBreaker#open][32]
-- [CircuitBreaker#shutdown][33]
-- [CircuitBreaker#fire][34]
-- [CircuitBreaker#cacheHit][35]
-- [CircuitBreaker#cacheMiss][36]
-- [CircuitBreaker#reject][37]
-- [CircuitBreaker#timeout][38]
-- [CircuitBreaker#success][39]
-- [CircuitBreaker#semaphoreLocked][40]
-- [CircuitBreaker#healthCheckFailed][41]
-- [CircuitBreaker#fallback][42]
-- [CircuitBreaker#failure][43]
-- [Status][44]
- - [Parameters][45]
- - [Examples][46]
- - [stats][47]
- - [window][48]
-- [Status#snapshot][49]
-
-## factory
-
-Creates a [CircuitBreaker][4] instance capable of executing `action`.
-
-### Parameters
-
-- `action` **[Function][50]** The action to fire for this [CircuitBreaker][4]
-- `options` **[Object][51]** Options for the [CircuitBreaker][4]
- - `options.timeout` **[Number][52]** The time in milliseconds that action should
- be allowed to execute before timing out. Default 10000 (10 seconds)
- - `options.maxFailures` **[Number][52]** (Deprecated) The number of times the
- circuit can fail before opening. Default 10.
- - `options.resetTimeout` **[Number][52]** The time in milliseconds to wait before
- setting the breaker to `halfOpen` state, and trying the action again.
- Default: 30000 (30 seconds)
- - `options.rollingCountTimeout` **[Number][52]** Sets the duration of the
- statistical rolling window, in milliseconds. This is how long Opossum keeps
- metrics for the circuit breaker to use and for publishing. Default: 10000
- - `options.rollingCountBuckets` **[Number][52]** Sets the number of buckets the
- rolling statistical window is divided into. So, if
- options.rollingCountTimeout is 10000, and options.rollingCountBuckets is 10,
- then the statistical window will be 1000 1 second snapshots in the
- statistical window. Default: 10
- - `options.name` **[String][53]** the circuit name to use when reporting stats.
- Default: the name of the function this circuit controls.
- - `options.rollingPercentilesEnabled` **[boolean][54]** This property indicates
- whether execution latencies should be tracked and calculated as percentiles.
- If they are disabled, all summary statistics (mean, percentiles) are
- returned as -1. Default: false
- - `options.capacity` **[Number][52]** the number of concurrent requests allowed.
- If the number currently executing function calls is equal to
- options.capacity, further calls to `fire()` are rejected until at least one
- of the current requests completes. Default: `Number.MAX_SAFE_INTEGER`.
- - `options.errorThresholdPercentage` **[Number][52]** the error percentage at
- which to open the circuit and start short-circuiting requests to fallback.
- Default: 50
- - `options.enabled` **[boolean][54]** whether this circuit is enabled upon
- construction. Default: true
- - `options.allowWarmUp` **[boolean][54]** determines whether to allow failures
- without opening the circuit during a brief warmup period (this is the
- `rollingCountDuration` property). Default: false
- allow before enabling the circuit. This can help in situations where no
- matter what your `errorThresholdPercentage` is, if the first execution
- times out or fails, the circuit immediately opens. Default: 0
- - `options.volumeThreshold` **[Number][52]** the minimum number of requests within
- the rolling statistical window that must exist before the circuit breaker
- can open. This is similar to `options.allowWarmUp` in that no matter how many
- failures there are, if the number of requests within the statistical window
- does not exceed this threshold, the circuit will remain closed. Default: 0
- - `options.errorFilter` **[Function][50]** an optional function that will be
- called when the circuit's function fails (returns a rejected Promise). If
- this function returns truthy, the circuit's failure statistics will not be
- incremented. This is useful, for example, when you don't want HTTP 404 to
- trip the circuit, but still want to handle it as a failure case.
-
-Returns **[CircuitBreaker][55]** a newly created [CircuitBreaker][4] instance
-
-## factory.circuits
-
-Get an Iterator
object containing all
-circuits that have been created but not subsequently shut down.
-
-Returns **Iterator** an Iterator
of all available circuits
+ - [close][3]
+ - [open][4]
+ - [shutdown][5]
+ - [isShutdown][6]
+ - [name][7]
+ - [group][8]
+ - [pendingClose][9]
+ - [closed][10]
+ - [opened][11]
+ - [halfOpen][12]
+ - [status][13]
+ - [stats][14]
+ - [enabled][15]
+ - [warmUp][16]
+ - [volumeThreshold][17]
+ - [fallback][18]
+ - [Parameters][19]
+ - [fire][20]
+ - [clearCache][21]
+ - [healthCheck][22]
+ - [Parameters][23]
+ - [enable][24]
+ - [disable][25]
+ - [circuits][26]
+- [CircuitBreaker#halfOpen][27]
+- [CircuitBreaker#close][28]
+- [CircuitBreaker#open][29]
+- [CircuitBreaker#shutdown][30]
+- [CircuitBreaker#fire][31]
+- [CircuitBreaker#cacheHit][32]
+- [CircuitBreaker#cacheMiss][33]
+- [CircuitBreaker#reject][34]
+- [CircuitBreaker#timeout][35]
+- [CircuitBreaker#success][36]
+- [CircuitBreaker#semaphoreLocked][37]
+- [CircuitBreaker#healthCheckFailed][38]
+- [CircuitBreaker#fallback][39]
+- [CircuitBreaker#failure][40]
+- [Status][41]
+ - [Parameters][42]
+ - [Examples][43]
+ - [stats][44]
+ - [window][45]
+- [Status#snapshot][46]
## CircuitBreaker
**Extends EventEmitter**
-Constructs a [CircuitBreaker][4].
+Constructs a [CircuitBreaker][1].
### Parameters
-- `action` **[Function][50]** The action to fire for this [CircuitBreaker][4]
-- `options` **[Object][51]** Options for the [CircuitBreaker][4]
- - `options.timeout` **[Number][52]** The time in milliseconds that action should
+- `action` **[Function][47]** The action to fire for this [CircuitBreaker][1]
+- `options` **[Object][48]** Options for the [CircuitBreaker][1]
+ - `options.timeout` **[Number][49]** The time in milliseconds that action should
be allowed to execute before timing out. Default 10000 (10 seconds)
- - `options.maxFailures` **[Number][52]** (Deprecated) The number of times the
+ - `options.maxFailures` **[Number][49]** (Deprecated) The number of times the
circuit can fail before opening. Default 10.
- - `options.resetTimeout` **[Number][52]** The time in milliseconds to wait before
+ - `options.resetTimeout` **[Number][49]** The time in milliseconds to wait before
setting the breaker to `halfOpen` state, and trying the action again.
Default: 30000 (30 seconds)
- - `options.rollingCountTimeout` **[Number][52]** Sets the duration of the
+ - `options.rollingCountTimeout` **[Number][49]** Sets the duration of the
statistical rolling window, in milliseconds. This is how long Opossum keeps
metrics for the circuit breaker to use and for publishing. Default: 10000
- - `options.rollingCountBuckets` **[Number][52]** Sets the number of buckets the
+ - `options.rollingCountBuckets` **[Number][49]** Sets the number of buckets the
rolling statistical window is divided into. So, if
options.rollingCountTimeout is 10000, and options.rollingCountBuckets is 10,
then the statistical window will be 1000 1 second snapshots in the
statistical window. Default: 10
- - `options.name` **[String][53]** the circuit name to use when reporting stats.
+ - `options.name` **[String][50]** the circuit name to use when reporting stats.
Default: the name of the function this circuit controls.
- - `options.rollingPercentilesEnabled` **[boolean][54]** This property indicates
+ - `options.rollingPercentilesEnabled` **[boolean][51]** This property indicates
whether execution latencies should be tracked and calculated as percentiles.
If they are disabled, all summary statistics (mean, percentiles) are
returned as -1. Default: false
- - `options.capacity` **[Number][52]** the number of concurrent requests allowed.
+ - `options.capacity` **[Number][49]** the number of concurrent requests allowed.
If the number currently executing function calls is equal to
options.capacity, further calls to `fire()` are rejected until at least one
of the current requests completes. Default: `Number.MAX_SAFE_INTEGER`.
- - `options.errorThresholdPercentage` **[Number][52]** the error percentage at
+ - `options.errorThresholdPercentage` **[Number][49]** the error percentage at
which to open the circuit and start short-circuiting requests to fallback.
Default: 50
- - `options.enabled` **[boolean][54]** whether this circuit is enabled upon
+ - `options.enabled` **[boolean][51]** whether this circuit is enabled upon
construction. Default: true
- - `options.allowWarmUp` **[boolean][54]** determines whether to allow failures
+ - `options.allowWarmUp` **[boolean][51]** determines whether to allow failures
without opening the circuit during a brief warmup period (this is the
`rollingCountDuration` property). Default: false
allow before enabling the circuit. This can help in situations where no
matter what your `errorThresholdPercentage` is, if the first execution
times out or fails, the circuit immediately opens. Default: 0
- - `options.volumeThreshold` **[Number][52]** the minimum number of requests within
+ - `options.volumeThreshold` **[Number][49]** the minimum number of requests within
the rolling statistical window that must exist before the circuit breaker
can open. This is similar to `options.allowWarmUp` in that no matter how many
failures there are, if the number of requests within the statistical window
does not exceed this threshold, the circuit will remain closed. Default: 0
- - `options.errorFilter` **[Function][50]** an optional function that will be
+ - `options.errorFilter` **[Function][47]** an optional function that will be
called when the circuit's function fails (returns a rejected Promise). If
this function returns truthy, the circuit's failPure statistics will not be
incremented. This is useful, for example, when you don't want HTTP 404 to
@@ -198,49 +131,49 @@ Returns **void**
Determines if the circuit has been shutdown.
-Type: [Boolean][54]
+Type: [Boolean][51]
### name
Gets the name of this circuit
-Type: [String][53]
+Type: [String][50]
### group
Gets the name of this circuit group
-Type: [String][53]
+Type: [String][50]
### pendingClose
Gets whether this cicruit is in the `pendingClosed` state
-Type: [Boolean][54]
+Type: [Boolean][51]
### closed
True if the circuit is currently closed. False otherwise.
-Type: [Boolean][54]
+Type: [Boolean][51]
### opened
True if the circuit is currently opened. False otherwise.
-Type: [Boolean][54]
+Type: [Boolean][51]
### halfOpen
True if the circuit is currently half opened. False otherwise.
-Type: [Boolean][54]
+Type: [Boolean][51]
### status
-The current [Status][16] of this [CircuitBreaker][4]
+The current [Status][13] of this [CircuitBreaker][1]
-Type: [Status][56]
+Type: [Status][52]
### stats
@@ -248,39 +181,39 @@ Type: [Status][56]
Get the current stats for the circuit.
-Type: [Object][51]
+Type: [Object][48]
### enabled
Gets whether the circuit is enabled or not
-Type: [Boolean][54]
+Type: [Boolean][51]
### warmUp
Gets whether the circuit is currently in warm up phase
-Type: [Boolean][54]
+Type: [Boolean][51]
### volumeThreshold
Gets the volume threshold for this circuit
-Type: [Boolean][54]
+Type: [Boolean][51]
### fallback
-Provide a fallback function for this [CircuitBreaker][4]. This
+Provide a fallback function for this [CircuitBreaker][1]. This
function will be executed when the circuit is `fire`d and fails.
It will always be preceded by a `failure` event, and `breaker.fire` returns
a rejected Promise.
#### Parameters
-- `func` **([Function][50] \| [CircuitBreaker][55])** the fallback function to execute
+- `func` **([Function][47] \| [CircuitBreaker][53])** the fallback function to execute
when the breaker has opened or when a timeout or error occurs.
-Returns **[CircuitBreaker][55]** this
+Returns **[CircuitBreaker][53]** this
### fire
@@ -289,12 +222,12 @@ returned promise will be rejected. If the action succeeds, the promise will
resolve with the resolved value from action. If a fallback function was
provided, it will be invoked in the event of any failure or timeout.
-Returns **[Promise][57]<any>** promise resolves with the circuit function's return
+Returns **[Promise][54]<any>** promise resolves with the circuit function's return
value on success or is rejected on failure of the action.
### clearCache
-Clears the cache of this [CircuitBreaker][4]
+Clears the cache of this [CircuitBreaker][1]
Returns **void**
@@ -312,12 +245,12 @@ circuit breaker itself.
#### Parameters
-- `func` **[Function][50]** a health check function which returns a promise.
-- `interval` **[Number][52]?** the amount of time between calls to the health
+- `func` **[Function][47]** a health check function which returns a promise.
+- `interval` **[Number][49]?** the amount of time between calls to the health
check function. Default: 5000 (5 seconds)
-- Throws **[TypeError][58]** if `interval` is supplied but not a number
+- Throws **[TypeError][55]** if `interval` is supplied but not a number
Returns **void**
@@ -351,7 +284,7 @@ Emitted after `options.resetTimeout` has elapsed, allowing for
a single attempt to call the service again. If that attempt is
successful, the circuit will be closed. Otherwise it remains open.
-Type: [Number][52]
+Type: [Number][49]
## CircuitBreaker#close
@@ -386,14 +319,14 @@ the cache, but the cache option is enabled.
Emitted when the circuit breaker is open and failing fast
-Type: [Error][59]
+Type: [Error][56]
## CircuitBreaker#timeout
Emitted when the circuit breaker action takes longer than
`options.timeout`
-Type: [Error][59]
+Type: [Error][56]
## CircuitBreaker#success
@@ -406,14 +339,14 @@ Type: any
Emitted when the rate limit has been reached and there
are no more locks to be obtained.
-Type: [Error][59]
+Type: [Error][56]
## CircuitBreaker#healthCheckFailed
Emitted with the user-supplied health check function
returns a rejected promise.
-Type: [Error][59]
+Type: [Error][56]
## CircuitBreaker#fallback
@@ -425,7 +358,7 @@ Type: any
Emitted when the circuit breaker action fails
-Type: [Error][59]
+Type: [Error][56]
## Status
@@ -433,27 +366,27 @@ Type: [Error][59]
- **See: CircuitBreaker#status**
-Tracks execution status for a given [CircuitBreaker][4].
-A Status instance is created for every [CircuitBreaker][4]
+Tracks execution status for a given [CircuitBreaker][1].
+A Status instance is created for every [CircuitBreaker][1]
and does not typically need to be created by a user.
-A Status instance will listen for all events on the [CircuitBreaker][4]
+A Status instance will listen for all events on the [CircuitBreaker][1]
and track them in a rolling statistical window. The window duration is
determined by the `rollingCountTimeout` option provided to the
-[CircuitBreaker][4]. The window consists of an array of Objects,
-each representing the counts for a [CircuitBreaker][4]'s events.
+[CircuitBreaker][1]. The window consists of an array of Objects,
+each representing the counts for a [CircuitBreaker][1]'s events.
-The array's length is determined by the [CircuitBreaker][4]'s
+The array's length is determined by the [CircuitBreaker][1]'s
`rollingCountBuckets` option. The duration of each slice of the window
is determined by dividing the `rollingCountTimeout` by
`rollingCountBuckets`.
### Parameters
-- `options` **[Object][51]** for the status window
- - `options.rollingCountBuckets` **[Number][52]** number of buckets in the window
- - `options.rollingCountTimeout` **[Number][52]** the duration of the window
- - `options.rollingPercentilesEnabled` **[Boolean][54]** whether to calculate
+- `options` **[Object][48]** for the status window
+ - `options.rollingCountBuckets` **[Number][49]** number of buckets in the window
+ - `options.rollingCountTimeout` **[Number][49]** the duration of the window
+ - `options.rollingPercentilesEnabled` **[Boolean][51]** whether to calculate
percentiles
### Examples
@@ -475,137 +408,131 @@ circuit.status.window;
Get the cumulative stats for the current window
-Type: [Object][51]
+Type: [Object][48]
### window
Gets the stats window as an array of time-sliced objects.
-Type: [Array][60]
+Type: [Array][57]
## Status#snapshot
Emitted at each time-slice. Listeners for this
event will receive a cumulative snapshot of the current status window.
-Type: [Object][51]
+Type: [Object][48]
-[1]: #factory
+[1]: #circuitbreaker
[2]: #parameters
-[3]: #factorycircuits
-
-[4]: #circuitbreaker
-
-[5]: #parameters-1
-
-[6]: #close
+[3]: #close
-[7]: #open
+[4]: #open
-[8]: #shutdown
+[5]: #shutdown
-[9]: #isshutdown
+[6]: #isshutdown
-[10]: #name
+[7]: #name
-[11]: #group
+[8]: #group
-[12]: #pendingclose
+[9]: #pendingclose
-[13]: #closed
+[10]: #closed
-[14]: #opened
+[11]: #opened
-[15]: #halfopen
+[12]: #halfopen
-[16]: #status
+[13]: #status
-[17]: #stats
+[14]: #stats
-[18]: #enabled
+[15]: #enabled
-[19]: #warmup
+[16]: #warmup
-[20]: #volumethreshold
+[17]: #volumethreshold
-[21]: #fallback
+[18]: #fallback
-[22]: #parameters-2
+[19]: #parameters-1
-[23]: #fire
+[20]: #fire
-[24]: #clearcache
+[21]: #clearcache
-[25]: #healthcheck
+[22]: #healthcheck
-[26]: #parameters-3
+[23]: #parameters-2
-[27]: #enable
+[24]: #enable
-[28]: #disable
+[25]: #disable
-[29]: #circuits
+[26]: #circuits
-[30]: #circuitbreakerhalfopen
+[27]: #circuitbreakerhalfopen
-[31]: #circuitbreakerclose
+[28]: #circuitbreakerclose
-[32]: #circuitbreakeropen
+[29]: #circuitbreakeropen
-[33]: #circuitbreakershutdown
+[30]: #circuitbreakershutdown
-[34]: #circuitbreakerfire
+[31]: #circuitbreakerfire
-[35]: #circuitbreakercachehit
+[32]: #circuitbreakercachehit
-[36]: #circuitbreakercachemiss
+[33]: #circuitbreakercachemiss
-[37]: #circuitbreakerreject
+[34]: #circuitbreakerreject
-[38]: #circuitbreakertimeout
+[35]: #circuitbreakertimeout
-[39]: #circuitbreakersuccess
+[36]: #circuitbreakersuccess
-[40]: #circuitbreakersemaphorelocked
+[37]: #circuitbreakersemaphorelocked
-[41]: #circuitbreakerhealthcheckfailed
+[38]: #circuitbreakerhealthcheckfailed
-[42]: #circuitbreakerfallback
+[39]: #circuitbreakerfallback
-[43]: #circuitbreakerfailure
+[40]: #circuitbreakerfailure
-[44]: #status-1
+[41]: #status-1
-[45]: #parameters-4
+[42]: #parameters-3
-[46]: #examples
+[43]: #examples
-[47]: #stats-1
+[44]: #stats-1
-[48]: #window
+[45]: #window
-[49]: #statussnapshot
+[46]: #statussnapshot
-[50]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function
+[47]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function
-[51]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
+[48]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
-[52]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
+[49]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
-[53]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
+[50]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
-[54]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
+[51]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
-[55]: #circuitbreaker
+[52]: #status
-[56]: #status
+[53]: #circuitbreaker
-[57]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise
+[54]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise
-[58]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/TypeError
+[55]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/TypeError
-[59]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error
+[56]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error
-[60]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
+[57]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
diff --git a/index.js b/index.js
index cbce0884..cae60bd9 100644
--- a/index.js
+++ b/index.js
@@ -1,79 +1,3 @@
'use strict';
-const CircuitBreaker = require('./lib/circuit');
-
-const defaults = {
- timeout: 10000, // 10 seconds
- errorThresholdPercentage: 50,
- resetTimeout: 30000 // 30 seconds
-};
-
-/**
- * Creates a {@link CircuitBreaker} instance capable of executing `action`.
- *
- * @param {Function} action The action to fire for this {@link CircuitBreaker}
- * @param {Object} options Options for the {@link CircuitBreaker}
- * @param {Number} options.timeout The time in milliseconds that action should
- * be allowed to execute before timing out. Default 10000 (10 seconds)
- * @param {Number} options.maxFailures (Deprecated) The number of times the
- * circuit can fail before opening. Default 10.
- * @param {Number} options.resetTimeout The time in milliseconds to wait before
- * setting the breaker to `halfOpen` state, and trying the action again.
- * Default: 30000 (30 seconds)
- * @param {Number} options.rollingCountTimeout Sets the duration of the
- * statistical rolling window, in milliseconds. This is how long Opossum keeps
- * metrics for the circuit breaker to use and for publishing. Default: 10000
- * @param {Number} options.rollingCountBuckets Sets the number of buckets the
- * rolling statistical window is divided into. So, if
- * options.rollingCountTimeout is 10000, and options.rollingCountBuckets is 10,
- * then the statistical window will be 1000 1 second snapshots in the
- * statistical window. Default: 10
- * @param {String} options.name the circuit name to use when reporting stats.
- * Default: the name of the function this circuit controls.
- * @param {boolean} options.rollingPercentilesEnabled This property indicates
- * whether execution latencies should be tracked and calculated as percentiles.
- * If they are disabled, all summary statistics (mean, percentiles) are
- * returned as -1. Default: false
- * @param {Number} options.capacity the number of concurrent requests allowed.
- * If the number currently executing function calls is equal to
- * options.capacity, further calls to `fire()` are rejected until at least one
- * of the current requests completes. Default: `Number.MAX_SAFE_INTEGER`.
- * @param {Number} options.errorThresholdPercentage the error percentage at
- * which to open the circuit and start short-circuiting requests to fallback.
- * Default: 50
- * @param {boolean} options.enabled whether this circuit is enabled upon
- * construction. Default: true
- * @param {boolean} options.allowWarmUp determines whether to allow failures
- * without opening the circuit during a brief warmup period (this is the
- * `rollingCountDuration` property). Default: false
- * allow before enabling the circuit. This can help in situations where no
- * matter what your `errorThresholdPercentage` is, if the first execution
- * times out or fails, the circuit immediately opens. Default: 0
- * @param {Number} options.volumeThreshold the minimum number of requests within
- * the rolling statistical window that must exist before the circuit breaker
- * can open. This is similar to `options.allowWarmUp` in that no matter how many
- * failures there are, if the number of requests within the statistical window
- * does not exceed this threshold, the circuit will remain closed. Default: 0
- * @param {Function} options.errorFilter an optional function that will be
- * called when the circuit's function fails (returns a rejected Promise). If
- * this function returns truthy, the circuit's failure statistics will not be
- * incremented. This is useful, for example, when you don't want HTTP 404 to
- * trip the circuit, but still want to handle it as a failure case.
- * @return {CircuitBreaker} a newly created {@link CircuitBreaker} instance
- */
-function factory(action, options) {
- return new CircuitBreaker(action,
- Object.assign({}, defaults, options));
-}
-
-/**
- * Get an Iterator
object containing all
- * circuits that have been created but not subsequently shut down.
- * @function factory.circuits
- * @return {Iterator} an Iterator
of all available circuits
- */
-factory.circuits = CircuitBreaker.circuits;
-
-module.exports = exports = factory;
-// Allow use of default import syntax in TypeScript
-module.exports.default = factory;
+module.exports = exports = require('./lib/circuit');
diff --git a/lib/circuit.js b/lib/circuit.js
index 1f712fb3..9cda2e1f 100644
--- a/lib/circuit.js
+++ b/lib/circuit.js
@@ -91,9 +91,13 @@ const CIRCUITS = new Set();
* @fires CircuitBreaker#failure
*/
class CircuitBreaker extends EventEmitter {
- constructor (action, options) {
+ constructor(action, options = {}) {
super();
this.options = options;
+ this.options.timeout = options.timeout || 10000;
+ this.options.resetTimeout = options.resetTimeout || 30000;
+ this.options.errorThresholdPercentage =
+ options.errorThresholdPercentage || 50;
this.options.rollingCountTimeout = options.rollingCountTimeout || 10000;
this.options.rollingCountBuckets = options.rollingCountBuckets || 10;
this.options.rollingPercentilesEnabled =
diff --git a/test/circuit-shutdown-test.js b/test/circuit-shutdown-test.js
index 23f57bb5..d55bf4f0 100644
--- a/test/circuit-shutdown-test.js
+++ b/test/circuit-shutdown-test.js
@@ -1,7 +1,7 @@
'use strict';
const test = require('tape');
-const circuit = require('..');
+const CircuitBreaker = require('..');
const passFail = require('./common').passFail;
// tests that we are not leaving listeners open to
@@ -9,7 +9,7 @@ const passFail = require('./common').passFail;
test('EventEmitter max listeners', t => {
let i = 100;
while (--i >= 0) {
- const breaker = circuit(passFail, { name: `passFail${i}` });
+ const breaker = new CircuitBreaker(passFail, { name: `passFail${i}` });
breaker.fire(1);
breaker.shutdown(); // required for cleanup
}
@@ -18,7 +18,7 @@ test('EventEmitter max listeners', t => {
test('Circuit shuts down properly', t => {
t.plan(5);
- const breaker = circuit(passFail);
+ const breaker = new CircuitBreaker(passFail);
t.ok(breaker.fire(1), 'breaker is active');
breaker.shutdown();
t.ok(breaker.isShutdown, 'breaker is shutdown');
@@ -39,18 +39,18 @@ test('A list of non-shutdown circuits is maintained', t => {
return count === 0;
}
- t.ok(expectCount(circuit.circuits(), 0));
+ t.ok(expectCount(CircuitBreaker.circuits(), 0));
- const c1 = circuit(passFail);
- const c2 = circuit(passFail);
+ const c1 = new CircuitBreaker(passFail);
+ const c2 = new CircuitBreaker(passFail);
- t.ok(expectCount(circuit.circuits(), 2));
+ t.ok(expectCount(CircuitBreaker.circuits(), 2));
c2.shutdown();
- t.ok(expectCount(circuit.circuits(), 1));
+ t.ok(expectCount(CircuitBreaker.circuits(), 1));
c1.shutdown();
- t.ok(expectCount(circuit.circuits(), 0));
+ t.ok(expectCount(CircuitBreaker.circuits(), 0));
t.end();
});
diff --git a/test/enable-disable-test.js b/test/enable-disable-test.js
index c0751608..132c4750 100644
--- a/test/enable-disable-test.js
+++ b/test/enable-disable-test.js
@@ -1,12 +1,12 @@
'use strict';
const test = require('tape');
-const opossum = require('../');
+const CircuitBreaker = require('../');
const { passFail } = require('./common');
test('Defaults to enabled', t => {
t.plan(1);
- const breaker = opossum(passFail);
+ const breaker = new CircuitBreaker(passFail);
t.equals(breaker.enabled, true);
breaker.shutdown();
t.end();
@@ -14,7 +14,7 @@ test('Defaults to enabled', t => {
test('Accepts options.enabled', t => {
t.plan(1);
- const breaker = opossum(passFail, { enabled: false });
+ const breaker = new CircuitBreaker(passFail, { enabled: false });
t.equals(breaker.enabled, false);
breaker.shutdown();
t.end();
@@ -27,7 +27,7 @@ test('When disabled the circuit should always be closed', t => {
resetTimeout: 1000
};
- const breaker = opossum(passFail, options);
+ const breaker = new CircuitBreaker(passFail, options);
breaker.disable();
breaker.fire(-1)
.catch(e => t.equals(e, 'Error: -1 is < 0'))
diff --git a/test/error-filter-test.js b/test/error-filter-test.js
index f5ec1c1f..6cce9a88 100644
--- a/test/error-filter-test.js
+++ b/test/error-filter-test.js
@@ -1,7 +1,7 @@
'use strict';
const test = require('tape');
-const opossum = require('../');
+const CircuitBreaker = require('../');
function mightFail (errorCode) {
const err = new Error('Something went wrong');
@@ -20,7 +20,7 @@ const options = {
test('Bypasses failure stats if errorFilter returns true', t => {
t.plan(3);
- const breaker = opossum(mightFail, options);
+ const breaker = new CircuitBreaker(mightFail, options);
breaker.fire(400)
.then(t.fail)
.catch(err => {
@@ -34,7 +34,7 @@ test('Bypasses failure stats if errorFilter returns true', t => {
test('Increments failure stats if errorFilter returns false', t => {
t.plan(3);
- const breaker = opossum(mightFail, options);
+ const breaker = new CircuitBreaker(mightFail, options);
breaker.fire(500)
.then(t.fail)
.catch(err => {
@@ -47,7 +47,8 @@ test('Increments failure stats if errorFilter returns false', t => {
test('Increments failure stats if no filter is provided', t => {
t.plan(3);
- const breaker = opossum(mightFail, { errorThresholdPercentage: 1 });
+ const breaker = new CircuitBreaker(mightFail,
+ { errorThresholdPercentage: 1 });
breaker.fire(500)
.then(t.fail)
.catch(err => {
diff --git a/test/half-open-test.js b/test/half-open-test.js
index 668502f7..8b37ce5e 100644
--- a/test/half-open-test.js
+++ b/test/half-open-test.js
@@ -1,7 +1,7 @@
'use strict';
const test = require('tape');
-const opossum = require('../');
+const CircuitBreaker = require('../');
const { timedFailingFunction } = require('./common');
test('When half-open, the circuit only allows one request through', t => {
@@ -11,8 +11,9 @@ test('When half-open, the circuit only allows one request through', t => {
resetTimeout: 100
};
- const breaker = opossum(timedFailingFunction, options);
+ const breaker = new CircuitBreaker(timedFailingFunction, options);
breaker.fire(1)
+ .then(t.fail)
.catch(e => t.equals(e, 'Failed after 1'))
.then(() => {
t.ok(breaker.opened, 'should be open after initial fire');
diff --git a/test/health-check-test.js b/test/health-check-test.js
index 2a3f5bd7..7bf0b9c3 100644
--- a/test/health-check-test.js
+++ b/test/health-check-test.js
@@ -1,12 +1,12 @@
'use strict';
const test = require('tape');
-const opossum = require('../');
+const CircuitBreaker = require('../');
const common = require('./common');
test('Circuits accept a health check function', t => {
t.plan(1);
- const circuit = opossum(common.passFail);
+ const circuit = new CircuitBreaker(common.passFail);
circuit.healthCheck(healthChecker(_ => {
t.ok(true, 'function called');
circuit.shutdown();
@@ -17,7 +17,7 @@ test('Circuits accept a health check function', t => {
test('healthCheckFailed is emitted on failure', t => {
t.plan(1);
- const circuit = opossum(common.passFail);
+ const circuit = new CircuitBreaker(common.passFail);
circuit.on('healthCheckFailed', e => {
t.equals(e.message, 'Too many tacos', 'healthCheckFailed emitted');
circuit.shutdown();
@@ -29,7 +29,7 @@ test('healthCheckFailed is emitted on failure', t => {
test('circuit opens on health check failure', t => {
t.plan(1);
- const circuit = opossum(common.passFail);
+ const circuit = new CircuitBreaker(common.passFail);
circuit.on('open', e => {
t.ok(circuit.opened, 'circuit opened');
circuit.shutdown();
@@ -42,7 +42,7 @@ test('circuit opens on health check failure', t => {
test('Health check function executes in the circuit breaker context', t => {
t.plan(1);
let called = false;
- const circuit = opossum(common.passFail);
+ const circuit = new CircuitBreaker(common.passFail);
circuit.healthCheck(function healthCheck () {
if (!called) {
t.equal(this, circuit, 'health check executes in circuit context');
@@ -56,7 +56,7 @@ test('Health check function executes in the circuit breaker context', t => {
test('healthCheck() throws TypeError if interval duration is NaN', t => {
t.plan(2);
- const circuit = opossum(common.passFail);
+ const circuit = new CircuitBreaker(common.passFail);
try {
circuit.healthCheck(_ => {}, 'Biscuits and gravy');
t.fail('Circuit breaker did not throw TypeError');
@@ -71,7 +71,7 @@ test('healthCheck() throws TypeError if interval duration is NaN', t => {
test('healthCheck() throws TypeError if parameter is not a function', t => {
t.plan(2);
- const circuit = opossum(common.passFail);
+ const circuit = new CircuitBreaker(common.passFail);
try {
circuit.healthCheck('Biscuits and gravy');
t.fail('Circuit breaker did not throw TypeError');
diff --git a/test/test.js b/test/test.js
index efaf4355..0d1983f2 100644
--- a/test/test.js
+++ b/test/test.js
@@ -3,12 +3,12 @@
const browser = require('./browser/browser-tap');
const test = require('tape');
const {promisify} = require('util');
-const circuit = require('../');
+const CircuitBreaker = require('../');
browser.enable();
test('api', t => {
- const breaker = circuit(passFail);
+ const breaker = new CircuitBreaker(passFail);
t.ok(breaker, 'CircuitBreaker');
t.ok(breaker.fire, 'CircuitBreaker.fire');
t.notOk(breaker.opened, 'CircuitBreaker.opened');
@@ -22,14 +22,14 @@ test('api', t => {
});
test('has a name based on the function name', t => {
- const breaker = circuit(passFail);
+ const breaker = new CircuitBreaker(passFail);
t.equals(breaker.name, passFail.name);
breaker.shutdown();
t.end();
});
test('accepts a name as an option', t => {
- const breaker = circuit(passFail, { name: 'tacoMachine' });
+ const breaker = new CircuitBreaker(passFail, { name: 'tacoMachine' });
t.equals(breaker.name, 'tacoMachine');
breaker.shutdown();
t.end();
@@ -37,21 +37,21 @@ test('accepts a name as an option', t => {
test('uses UUID as a name when none is provided and the function is anonymoys',
t => {
- const breaker = circuit(identity);
+ const breaker = new CircuitBreaker(identity);
t.ok(breaker.name);
breaker.shutdown();
t.end();
});
test('accepts a group as an option', t => {
- const breaker = circuit(passFail, { group: 'tacoMachine' });
+ const breaker = new CircuitBreaker(passFail, { group: 'tacoMachine' });
t.equals(breaker.group, 'tacoMachine');
breaker.shutdown();
t.end();
});
test('uses name as a group when no group is provided', t => {
- const breaker = circuit(passFail, { name: 'tacoMachine' });
+ const breaker = new CircuitBreaker(passFail, { name: 'tacoMachine' });
t.equals(breaker.group, 'tacoMachine');
breaker.shutdown();
t.end();
@@ -60,7 +60,7 @@ test('uses name as a group when no group is provided', t => {
test('Passes parameters to the circuit function', t => {
t.plan(1);
const expected = 34;
- const breaker = circuit(passFail);
+ const breaker = new CircuitBreaker(passFail);
breaker.fire(expected)
.then(arg => t.equals(arg, expected, 'function parameters provided'))
@@ -75,7 +75,7 @@ test('Using cache', t => {
const options = {
cache: true
};
- const breaker = circuit(passFail, options);
+ const breaker = new CircuitBreaker(passFail, options);
breaker.fire(expected)
.then(arg => {
@@ -115,7 +115,7 @@ test('Using cache', t => {
test('Fails when the circuit function fails', t => {
t.plan(1);
- const breaker = circuit(passFail);
+ const breaker = new CircuitBreaker(passFail);
breaker.fire(-1)
.then(() => t.fail)
@@ -130,7 +130,7 @@ test('Fails when the circuit function times out', t => {
t.plan(2);
const expected = 'Timed out after 10ms';
const expectedCode = 'ETIMEDOUT';
- const breaker = circuit(slowFunction, { timeout: 10 });
+ const breaker = new CircuitBreaker(slowFunction, { timeout: 10 });
breaker.fire()
.then(t.fail)
@@ -144,7 +144,7 @@ test('Fails when the circuit function times out', t => {
test('Works with functions that do not return a promise', t => {
t.plan(1);
- const breaker = circuit(nonPromise);
+ const breaker = new CircuitBreaker(nonPromise);
breaker.fire()
.then(arg => t.equals(arg, 'foo', 'non-Promise returns expected value'))
@@ -155,7 +155,7 @@ test('Works with functions that do not return a promise', t => {
test('Works with non-functions', t => {
t.plan(1);
- const breaker = circuit('foobar');
+ const breaker = new CircuitBreaker('foobar');
breaker.fire()
.then(arg => t.equals(arg, 'foobar', 'expected raw value returns'))
@@ -167,7 +167,7 @@ test('Works with non-functions', t => {
test('Works with callback functions', t => {
t.plan(1);
const promisified = promisify(callbackFunction);
- const breaker = circuit(promisified);
+ const breaker = new CircuitBreaker(promisified);
breaker.fire(3, 4)
.then(arg => t.equals(arg, 7, 'Works with a Promisified Callback'))
@@ -179,7 +179,7 @@ test('Works with callback functions', t => {
test('Works with callback functions that fail', t => {
t.plan(1);
const promisified = promisify(failedCallbackFunction);
- const breaker = circuit(promisified);
+ const breaker = new CircuitBreaker(promisified);
breaker.fire(3, 4)
.then(t.fail)
@@ -190,7 +190,8 @@ test('Works with callback functions that fail', t => {
test('Breaker opens after a configurable number of failures', t => {
t.plan(2);
- const breaker = circuit(passFail, { errorThresholdPercentage: 10 });
+ const breaker = new CircuitBreaker(passFail,
+ { errorThresholdPercentage: 10 });
breaker.fire(-1)
.then(t.fail)
@@ -211,7 +212,7 @@ test('Breaker resets after a configurable amount of time', t => {
t.plan(1);
const fails = -1;
const resetTimeout = 100;
- const breaker = circuit(passFail,
+ const breaker = new CircuitBreaker(passFail,
{ errorThresholdPercentage: 1, resetTimeout });
breaker.fire(fails)
@@ -229,7 +230,7 @@ test('Breaker resets after a configurable amount of time', t => {
test('Breaker status reflects open state', t => {
t.plan(1);
- const breaker = circuit(passFail,
+ const breaker = new CircuitBreaker(passFail,
{ errorThresholdPercentage: 0, resetTimeout: 100 });
breaker.fire(-1)
.then(t.fail)
@@ -242,7 +243,7 @@ test('Breaker resets for circuits with a fallback function', t => {
t.plan(2);
const fails = -1;
const resetTimeout = 100;
- const breaker = circuit(passFail,
+ const breaker = new CircuitBreaker(passFail,
{ errorThresholdPercentage: 1, resetTimeout });
breaker.fallback(x => x * 2);
@@ -268,7 +269,7 @@ test('Executes fallback action, if one exists, when breaker is open', t => {
t.plan(1);
const fails = -1;
const expected = 100;
- const breaker = circuit(passFail, { errorThresholdPercentage: 1 });
+ const breaker = new CircuitBreaker(passFail, { errorThresholdPercentage: 1 });
breaker.fallback(() => expected);
breaker.fire(fails)
.then(() => {
@@ -283,7 +284,7 @@ test('Executes fallback action, if one exists, when breaker is open', t => {
test('Passes error as last argument to the fallback function', t => {
t.plan(1);
const fails = -1;
- const breaker = circuit(passFail, { errorThresholdPercentage: 1 });
+ const breaker = new CircuitBreaker(passFail, { errorThresholdPercentage: 1 });
breaker.on('fallback', result => {
t.equals(result,
`Error: ${fails} is < 0`, 'fallback received error as last parameter');
@@ -298,7 +299,7 @@ test('Fallback called once for the same execution when timing out', t => {
t.plan(1);
const actionDuration = 200;
- const breaker = circuit(timedFailingFunction,
+ const breaker = new CircuitBreaker(timedFailingFunction,
{ timeout: actionDuration / 2 });
breaker.fallback((ms, err) => {
@@ -317,7 +318,7 @@ test('Fallback called once for the same execution when timing out', t => {
test('Passes arguments to the fallback function', t => {
t.plan(1);
const fails = -1;
- const breaker = circuit(passFail, { errorThresholdPercentage: 1 });
+ const breaker = new CircuitBreaker(passFail, { errorThresholdPercentage: 1 });
breaker.on('fallback', result => {
t.equals(result, fails, 'fallback received expected parameters');
breaker.shutdown();
@@ -328,7 +329,7 @@ test('Passes arguments to the fallback function', t => {
test('Returns self from fallback()', t => {
t.plan(1);
- const breaker = circuit(passFail, { errorThresholdPercentage: 1 });
+ const breaker = new CircuitBreaker(passFail, { errorThresholdPercentage: 1 });
breaker.fallback(noop);
breaker.fire(1)
.then(result => {
@@ -341,7 +342,8 @@ test('Returns self from fallback()', t => {
test('CircuitBreaker emits failure when action throws', t => {
t.plan(2);
- const breaker = circuit(() => { throw new Error('E_TOOMANYCHICKENTACOS'); });
+ const breaker = new CircuitBreaker(
+ () => { throw new Error('E_TOOMANYCHICKENTACOS'); });
breaker.fire()
.then(t.fail)
.catch(e => {
@@ -354,7 +356,8 @@ test('CircuitBreaker emits failure when action throws', t => {
test('CircuitBreaker executes fallback when an action throws', t => {
t.plan(3);
- const breaker = circuit(() => { throw new Error('E_TOOMANYCHICKENTACOS'); })
+ const breaker = new CircuitBreaker(
+ () => { throw new Error('E_TOOMANYCHICKENTACOS'); })
.fallback(() => 'Fallback executed');
breaker.fire()
.then(result => {
@@ -370,7 +373,7 @@ test('CircuitBreaker executes fallback when an action throws', t => {
test('CircuitBreaker emits failure when falling back', t => {
t.plan(2);
- const breaker = circuit(passFail).fallback(() => 'fallback value');
+ const breaker = new CircuitBreaker(passFail).fallback(() => 'fallback value');
breaker.on('failure', err => {
t.equals('Error: -1 is < 0', err, 'Expected failure');
@@ -386,7 +389,7 @@ test('CircuitBreaker emits failure when falling back', t => {
test('CircuitBreaker status', t => {
t.plan(12);
- const breaker = circuit(passFail, { errorThresholdPercentage: 1 });
+ const breaker = new CircuitBreaker(passFail, { errorThresholdPercentage: 1 });
const deepEqual = (t, expected) =>
actual => t.deepEqual(actual, expected, 'expected status values');
@@ -429,7 +432,7 @@ test('CircuitBreaker status', t => {
test('CircuitBreaker rolling counts', t => {
const opts = { rollingCountTimeout: 200, rollingCountBuckets: 2 };
- const breaker = circuit(passFail, opts);
+ const breaker = new CircuitBreaker(passFail, opts);
const deepEqual = (t, expected) =>
actual => t.deepEqual(actual, expected, 'expected status values');
Promise.all([
@@ -454,7 +457,7 @@ test('CircuitBreaker rolling counts', t => {
test('CircuitBreaker status listeners', t => {
const opts = { rollingCountTimeout: 2500, rollingCountBuckets: 25 };
- const breaker = circuit(passFail, opts);
+ const breaker = new CircuitBreaker(passFail, opts);
breaker.status.on('snapshot', snapshot => {
t.ok(snapshot.successes !== undefined, 'has successes stat');
@@ -473,7 +476,7 @@ test('CircuitBreaker status listeners', t => {
test('CircuitBreaker fallback event', t => {
t.plan(1);
- const breaker = circuit(passFail, { errorThresholdPercentage: 0 });
+ const breaker = new CircuitBreaker(passFail, { errorThresholdPercentage: 0 });
breaker.fallback(x => x);
breaker.on('fallback', value => {
t.equal(value, -1, 'fallback value received');
@@ -491,7 +494,7 @@ test('CircuitBreaker events', t => {
resetTimeout: 500
};
- const breaker = circuit(passFail, options);
+ const breaker = new CircuitBreaker(passFail, options);
let fired = 0;
let failures = 0;
let success = 0;
@@ -575,7 +578,8 @@ test('CircuitBreaker events', t => {
t.equals(timeout, 0, 'timeout event did not fire');
})
.then(() => {
- const timeoutBreaker = circuit(slowFunction, options);
+ const timeoutBreaker = new CircuitBreaker(slowFunction,
+ options);
let timedOut = false;
timeoutBreaker.on('timeout', () => timedOut++);
timeoutBreaker.fire().then(t.fail).catch(noop);
@@ -596,7 +600,7 @@ test('circuit halfOpen', t => {
resetTimeout: 100
};
- const breaker = circuit(passFail, options);
+ const breaker = new CircuitBreaker(passFail, options);
breaker.fire(-1)
.catch(e => t.equals(e, 'Error: -1 is < 0', 'function should fail'))
.then(() => {
@@ -647,7 +651,7 @@ test('CircuitBreaker fallback as a rejected promise', t => {
resetTimeout: 100
};
const input = -1;
- const breaker = circuit(passFail, options);
+ const breaker = new CircuitBreaker(passFail, options);
breaker.fallback(() => Promise.reject(new Error('nope')));
breaker.fire(input).then(t.fail).catch(e => {
@@ -662,7 +666,7 @@ test('CircuitBreaker fallback event as a rejected promise', t => {
resetTimeout: 100
};
const input = -1;
- const breaker = circuit(passFail, options);
+ const breaker = new CircuitBreaker(passFail, options);
breaker.fallback(() => Promise.reject(new Error('nope')));
breaker.on('fallback', result => {
@@ -684,8 +688,8 @@ test('CircuitBreaker fallback as a CircuitBreaker', t => {
};
const input = -1;
- const breaker = circuit(passFail, options);
- breaker.fallback(circuit(x => x, options));
+ const breaker = new CircuitBreaker(passFail, options);
+ breaker.fallback(new CircuitBreaker(x => x, options));
breaker.fire(input)
.then(v => t.equals(v, input, 'Fallback value equals input'))
@@ -701,8 +705,8 @@ test('CircuitBreaker fallback as a CircuitBreaker that fails', t => {
};
const input = -1;
- const breaker = circuit(passFail, options);
- breaker.fallback(circuit(passFail, options));
+ const breaker = new CircuitBreaker(passFail, options);
+ breaker.fallback(new CircuitBreaker(passFail, options));
breaker.fire(input)
.catch(e => t.equals(e, 'Error: -1 is < 0', 'Breaker should fail'))
@@ -718,8 +722,8 @@ test('CircuitBreaker fallback as a CircuitBreaker', t => {
};
const input = -1;
- const breaker = circuit(passFail, options);
- breaker.fallback(circuit(x => x, options));
+ const breaker = new CircuitBreaker(passFail, options);
+ breaker.fallback(new CircuitBreaker(x => x, options));
breaker.fire(input)
.then(v => t.equals(v, input, 'Fallback value equals input'))
@@ -738,11 +742,11 @@ Please use options.errorThresholdPercentage`;
console.error = originalLog;
t.end();
};
- circuit(passFail, options);
+ new CircuitBreaker(passFail, options);
});
test('rolling percentile enabled option defaults to true', t => {
- const breaker = circuit(passFail);
+ const breaker = new CircuitBreaker(passFail);
t.equals(breaker.status.rollingPercentilesEnabled, true,
'rollingPercentilesEnabled should default to true');
t.equals(breaker.status.stats.latencyMean, 0,
@@ -757,7 +761,7 @@ test('rolling percentile enabled option defaults to true', t => {
test('rolling percentile enabled option set to false', t => {
const options = { rollingPercentilesEnabled: false };
- const breaker = circuit(passFail, options);
+ const breaker = new CircuitBreaker(passFail, options);
t.equals(breaker.status.rollingPercentilesEnabled, false,
'rollingPercentilesEnabled set to false');
t.equals(breaker.status.stats.latencyMean, -1,
@@ -772,7 +776,7 @@ test('rolling percentile enabled option set to false', t => {
test('Circuit Breaker success event emits latency', t => {
t.plan(1);
- const breaker = circuit(passFail);
+ const breaker = new CircuitBreaker(passFail);
breaker.on('success', (result, latencyTime) => {
t.ok(latencyTime, 'second argument is the latency');
breaker.shutdown();
@@ -784,7 +788,7 @@ test('Circuit Breaker success event emits latency', t => {
test('Circuit Breaker failure event emits latency', t => {
t.plan(1);
- const breaker = circuit(passFail);
+ const breaker = new CircuitBreaker(passFail);
breaker.on('failure', (result, latencyTime) => {
t.ok(latencyTime, 'second argument is the latency');
breaker.shutdown();
@@ -796,7 +800,7 @@ test('Circuit Breaker failure event emits latency', t => {
test('Circuit Breaker failure event emits function parameters', t => {
t.plan(6);
- const breaker = circuit(passFail);
+ const breaker = new CircuitBreaker(passFail);
breaker.on('failure', (result, latencyTime, args) => {
t.ok(args, 'third argument is the function args');
t.equal(Array.isArray(args), true, 'The args parameter is an array');
@@ -813,7 +817,7 @@ test('Circuit Breaker failure event emits function parameters', t => {
test('Circuit Breaker timeout event emits latency', t => {
t.plan(1);
- const breaker = circuit(slowFunction, { timeout: 10 });
+ const breaker = new CircuitBreaker(slowFunction, { timeout: 10 });
breaker.on('timeout', (result, latencyTime) => {
t.ok(latencyTime, 'second argument is the latency');
@@ -826,7 +830,7 @@ test('Circuit Breaker timeout event emits latency', t => {
test('Circuit Breaker timeout event emits function parameters', t => {
t.plan(6);
- const breaker = circuit(slowFunction, { timeout: 10 });
+ const breaker = new CircuitBreaker(slowFunction, { timeout: 10 });
breaker.on('timeout', (result, latencyTime, args) => {
t.ok(args, 'third argument is the function args');
@@ -844,7 +848,8 @@ test('Circuit Breaker timeout event emits function parameters', t => {
test('Circuit Breaker timeout with semaphore released', t => {
t.plan(1);
- const breaker = circuit(slowFunction, { timeout: 10, capacity: 2 });
+ const breaker = new CircuitBreaker(slowFunction,
+ { timeout: 10, capacity: 2 });
breaker.on('timeout', _ => {
t.equal(breaker.semaphore.count, breaker.options.capacity);
@@ -857,7 +862,8 @@ test('Circuit Breaker timeout with semaphore released', t => {
test('CircuitBreaker semaphore rate limiting', t => {
t.plan(2);
- const breaker = circuit(timedFunction, { timeout: 300, capacity: 1 });
+ const breaker = new CircuitBreaker(timedFunction,
+ { timeout: 300, capacity: 1 });
// fire once to acquire the semaphore and hold it for a long time
breaker.fire(1000).catch(noop);
@@ -872,7 +878,7 @@ test('CircuitBreaker semaphore rate limiting', t => {
});
test('CircuitBreaker default capacity', t => {
- const breaker = circuit(passFail);
+ const breaker = new CircuitBreaker(passFail);
t.equals(breaker.options.capacity, Number.MAX_SAFE_INTEGER);
breaker.shutdown();
t.end();
diff --git a/test/volume-threshold-test.js b/test/volume-threshold-test.js
index 4f74c2d6..ca36cfd8 100644
--- a/test/volume-threshold-test.js
+++ b/test/volume-threshold-test.js
@@ -1,7 +1,7 @@
'use strict';
const test = require('tape');
-const opossum = require('../');
+const CircuitBreaker = require('../');
const { passFail } = require('./common');
test('By default does not have a volume threshold', t => {
@@ -11,7 +11,7 @@ test('By default does not have a volume threshold', t => {
resetTimeout: 100
};
- const breaker = opossum(passFail, options);
+ const breaker = new CircuitBreaker(passFail, options);
breaker.fire(-1)
.catch(e => t.equals(e, 'Error: -1 is < 0'))
.then(() => {
@@ -31,7 +31,7 @@ test('Has a volume threshold before tripping when option is provided', t => {
volumeThreshold: 3
};
- const breaker = opossum(passFail, options);
+ const breaker = new CircuitBreaker(passFail, options);
breaker.fire(-1)
.then(t.fail)
.catch(e => {
@@ -73,7 +73,7 @@ test('volume threshold does not affect halfOpen state', t => {
volumeThreshold: 2
};
- const breaker = opossum(passFail, options);
+ const breaker = new CircuitBreaker(passFail, options);
breaker.fire(-1)
.then(t.fail)
.catch(_ => {
diff --git a/test/warmup-test.js b/test/warmup-test.js
index 66906967..0c5900e1 100644
--- a/test/warmup-test.js
+++ b/test/warmup-test.js
@@ -1,7 +1,7 @@
'use strict';
const test = require('tape');
-const opossum = require('../');
+const CircuitBreaker = require('../');
const { passFail } = require('./common');
test('By default does not allow for warmup', t => {
@@ -11,7 +11,7 @@ test('By default does not allow for warmup', t => {
resetTimeout: 100
};
- const breaker = opossum(passFail, options);
+ const breaker = new CircuitBreaker(passFail, options);
breaker.fire(-1)
.catch(e => t.equals(e, 'Error: -1 is < 0'))
.then(() => {
@@ -31,7 +31,7 @@ test('Allows for warmup when option is provided', t => {
allowWarmUp: true
};
- const breaker = opossum(passFail, options);
+ const breaker = new CircuitBreaker(passFail, options);
breaker.fire(-1)
.catch(e => t.equals(e, 'Error: -1 is < 0'))
.then(() => {
@@ -52,7 +52,7 @@ test('Only warms up for rollingCountTimeout', t => {
rollingCountTimeout: 500
};
- const breaker = opossum(passFail, options);
+ const breaker = new CircuitBreaker(passFail, options);
breaker.fire(-1)
.catch(e => t.equals(e, 'Error: -1 is < 0'))
.then(() => {