Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

opossum

Package Overview
Dependencies
Maintainers
4
Versions
67
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

opossum - npm Package Compare versions

Comparing version 3.0.0 to 4.0.0

9

CHANGELOG.md

@@ -5,2 +5,11 @@ # Changelog

## [4.0.0](https://github.com/nodeshift/opossum/compare/v3.1.0...v4.0.0) (2019-08-21)
## [3.1.0](https://github.com/nodeshift/opossum/compare/v3.0.0...v3.1.0) (2019-08-21)
### Features
* refactor Prometheus and Hystrix metrics ([#350](https://github.com/nodeshift/opossum/issues/350)) ([3adbb90](https://github.com/nodeshift/opossum/commit/3adbb90))
## [3.0.0](https://github.com/nodeshift/opossum/compare/v2.3.0...v3.0.0) (2019-07-26)

@@ -7,0 +16,0 @@

105

index.js
'use strict';
const CircuitBreaker = require('./lib/circuit');
let lastCircuit;
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) {
lastCircuit = new CircuitBreaker(action,
Object.assign({}, defaults, options));
return lastCircuit;
}
/**
* Get the Prometheus metrics for all circuits.
* @function factory.metrics
* @return {String} the metrics for all circuits or
* undefined if no circuits have been created
*/
factory.metrics = function metrics() {
// Just get the metrics for the last circuit that was created
// since prom-client is additive
if (lastCircuit && lastCircuit.metrics) return lastCircuit.metrics.metrics;
}
let warningIssued = false;
Object.defineProperty(factory, 'stats', {
get: _ => {
if (!warningIssued) {
warningIssued = true;
console.warn(`WARNING: Hystrics stats are deprecated
See: https://github.com/Netflix/Hystrix#dashboard`)
}
return require('./lib/hystrix-stats').stream;
}
});
/**
* Get an <code>Iterator</code> object containing all
* circuits that have been created but not subsequently shut down.
* @function factory.circuits
* @return {Iterator} an <code>Iterator</code> 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');

@@ -5,8 +5,3 @@ 'use strict';

const Status = require('./status');
const HystrixStats = require('./hystrix-stats');
const Semaphore = require('./semaphore');
let PrometheusMetrics;
if (!process.env.WEB) {
PrometheusMetrics = require('./prometheus-metrics');
}

@@ -23,4 +18,2 @@ const STATE = Symbol('state');

const GROUP = Symbol('group');
const HYSTRIX_STATS = Symbol('hystrix-stats');
const PROMETHEUS_METRICS = Symbol('prometheus-metrics');
const CACHE = new WeakMap();

@@ -32,7 +25,3 @@ const ENABLED = Symbol('Enabled');

Please use options.errorThresholdPercentage`;
const CIRCUITS = new Set();
let warningIssued = false;
/**

@@ -88,3 +77,3 @@ * Constructs a {@link CircuitBreaker}.

* called when the circuit's function fails (returns a rejected Promise). If
* this function returns truthy, the circuit's failure statistics will not be
* 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

@@ -108,5 +97,9 @@ * trip the circuit, but still want to handle it as a failure case.

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;

@@ -189,14 +182,2 @@ this.options.rollingCountBuckets = options.rollingCountBuckets || 10;

}
// Register with the hystrix stats listener
this[HYSTRIX_STATS] = new HystrixStats(this);
// Add Prometheus metrics if not running in a web env
if (PrometheusMetrics && options.usePrometheus) {
this[PROMETHEUS_METRICS] = new PrometheusMetrics(
this,
options.prometheusRegistry
);
}
CIRCUITS.add(this);
}

@@ -250,6 +231,8 @@

this.status.shutdown();
this.hystrixStats.shutdown();
this.metrics && this.metrics.clear();
this[STATE] = SHUTDOWN;
CIRCUITS.delete(this);
/**
* Emitted when the circuit breaker has been shut down.
* @event CircuitBreaker#shutdown
*/
this.emit('shutdown');
}

@@ -331,23 +314,2 @@

/**
* Get the hystrixStats.
* @type {HystrixStats}
*/
get hystrixStats () {
if (!warningIssued) {
warningIssued = true;
console.warn(`WARNING: Hystrics stats are deprecated
See: https://github.com/Netflix/Hystrix#dashboard`)
}
return this[HYSTRIX_STATS];
}
/**
* Get the prometheus metrics for this circuit
* @type {PrometheusMetrics}
*/
get metrics () {
return this[PROMETHEUS_METRICS];
}
/**
* Gets whether the circuit is enabled or not

@@ -677,13 +639,2 @@ * @type {Boolean}

/**
* Gets a Set iterator of all active circuits. If a circuit
* has been created, but subsequently shut down, it will not
* be included in the Set iterator.
*
* @returns {Iterator} an Iterator object containing a reference
* to all {CircuitBreaker} instances that have been created.
*/
CircuitBreaker.circuits = function circuits() {
return CIRCUITS.values();
}
module.exports = exports = CircuitBreaker;

@@ -9,3 +9,3 @@ 'use strict';

let sem = {
const sem = {
take,

@@ -12,0 +12,0 @@ release,

{
"name": "opossum",
"version": "3.0.0",
"version": "4.0.0",
"author": "Red Hat, Inc.",

@@ -59,7 +59,7 @@ "license": "Apache-2.0",

"serve": "^11.0.0",
"standard-version": "6.0.1",
"standardx": "^3.0.1",
"standard-version": "7.0.0",
"standardx": "^5.0.0",
"tap-spec": "~5.0.0",
"tape": "~4.11.0",
"webpack": "~4.38.0",
"webpack": "~4.39.0",
"webpack-cli": "~3.3.0"

@@ -77,5 +77,3 @@ },

],
"dependencies": {
"prom-client": "^11.2.1"
}
"dependencies": {}
}

@@ -36,3 +36,3 @@ # opossum [![CircleCI](https://circleci.com/gh/nodeshift/opossum/tree/master.svg?style=svg&circle-token=0742302baa8c95cef354997ea52a383d3d078ff1)](https://circleci.com/gh/nodeshift/opossum/tree/master)

```javascript
const circuitBreaker = require('opossum');
const CircuitBreaker = require('opossum');

@@ -50,3 +50,3 @@ function asyncFunctionThatCouldFail (x, y) {

};
const breaker = circuitBreaker(asyncFunctionThatCouldFail, options);
const breaker = new CircuitBreaker(asyncFunctionThatCouldFail, options);

@@ -65,3 +65,3 @@ breaker.fire(params)

```javascript
const breaker = circuitBreaker(asyncFunctionThatCouldFail, options);
const breaker = new CircuitBreaker(asyncFunctionThatCouldFail, options);
// if asyncFunctionThatCouldFail starts to fail, firing the breaker

@@ -130,3 +130,3 @@ // will trigger our fallback function

```
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

@@ -144,3 +144,3 @@ API calls.

const circuit = circuitBreaker(() => $.get(route), circuitBreakerOptions);
const circuit = new CircuitBreaker(() => $.get(route), circuitBreakerOptions);
circuit.fallback(() => `${route} unavailable right now. Try later.`));

@@ -175,3 +175,3 @@ circuit.on('success', (result) => $(element).append(JSON.stringify(result)}));

```js
const circuit = circuitBreaker(() => $.get(route), circuitBreakerOptions);
const circuit = new CircuitBreaker(() => $.get(route), circuitBreakerOptions);

@@ -220,6 +220,6 @@ circuit.fallback(() => ({ body: `${route} unavailable right now. Try later.` }));

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);

@@ -235,3 +235,3 @@ breaker.fire('./package.json', 'utf-8')

```javascript
const breaker = circuitBreaker('foo', options);
const breaker = new CircuitBreaker('foo', options);

@@ -252,52 +252,12 @@ breaker.fire()

#### Prometheus
Provide `{ usePrometheus: true }` in the options when creating a circuit to produce
metrics that are consumable by Prometheus. These metrics include information about
the circuit itself, for example how many times it has opened, as well as general Node.js
statistics, for example event loop lag. To get consolidated metrics for all circuits in your
application, use the `metrics()` function on the factory.
The [`opossum-prometheus`](https://github.com/nodeshift/opossum-prometheus) module
can be used to produce metrics that are consumable by Prometheus.
These metrics include information about the circuit itself, for example how many
times it has opened, as well as general Node.js statistics, for example event loop lag.
```js
const opossum = require('opossum');
// create a circuit
const circuit = opossum(functionThatMightFail, { usePrometheus: true });
// In an express app, expose the metrics to the Prometheus server
app.use('/metrics', (req, res) => {
res.type('text/plain');
res.send(opossum.metrics());
});
```
The `prometheusRegistry` option allows to provide a existing
[prom-client](https://github.com/siimon/prom-client) registry.
The metrics about the circuit will be added to the provided registry instead
of the global registry.
The [default metrics](https://github.com/siimon/prom-client#default-metrics)
will not be added to the provided registry.
```js
const opossum = require('opossum');
const { Registry } = require('prom-client');
// Create a registry
const prometheusRegistry = new Registry();
// create a circuit
const circuit = opossum(functionThatMightFail, {
usePrometheus: true,
prometheusRegistry
});
```
#### Hystrix
The [`opossum-hystrix`](https://github.com/nodeshift/opossum-hystrix) module can
be used to produce metrics that are consumable by the Hystrix Dashboard.
**NOTE: Hystrix metrics are deprecated**
A Hystrix Stream is available for use with a Hystrix Dashboard using the `circuitBreaker.hystrixStats.getHystrixStream` method.
This method returns a [Node.js Stream](https://nodejs.org/api/stream.html), which makes it easy to create an SSE stream that will be compliant with a Hystrix Dashboard.
Additional Reading: [Hystrix Metrics Event Stream](https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-metrics-event-stream), [Turbine](https://github.com/Netflix/Turbine/wiki), [Hystrix Dashboard](https://github.com/Netflix/Hystrix/wiki/Dashboard)
## Troubleshooting

@@ -315,3 +275,3 @@

This typically occurs when you have created more than ten `CircuitBreaker` instances. This is due to the fact that every circuit created is adding a listener to the stream accessed via `circuit.stats.getHystrixStream()`, and the default `EventEmitter` listener limit is 10. In some cases, seeing this error might indicate a bug in client code, where many `CircuitBreaker`s are inadvertently being created. But there are legitimate scenarios where this may not be the case. For example, it could just be that you need more than 10 `CircuitBreaker`s in your app. That's ok.
In some cases, seeing this error might indicate a bug in client code, where many `CircuitBreaker`s are inadvertently being created. But there are legitimate scenarios where this may not be the case. For example, it could just be that you need more than 10 `CircuitBreaker`s in your app. That's ok.

@@ -318,0 +278,0 @@ To get around the error, you can set the number of listeners on the stream.

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc