Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add isPromise #61

Merged
merged 1 commit into from
Nov 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ isOpen|N/A|boolean|Returns `true` if circuit is open
- **healthCheckInterval**: time in `ms` interval between each execution of health check function
- **healthCheck**: function to call for the health check (can be defined also with calling `healthCheck` function)
- **fallback**: function to call for fallback (can be defined also with calling `fallback` function)
- **isPromise**: `boolean` to opt out of check for callback in function. This affects the passed in function, health check and fallback
- **isFunction**: `boolean` to opt out of check for callback, always promisifying in function. This affects the passed in function, health check and fallback

## Stats
Based on the `opts.statInterval` an event will be fired at regular intervals that contains a snapshot of the running state of the application.
Expand Down
26 changes: 13 additions & 13 deletions lib/Brakes.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const EventEmitter = require('events').EventEmitter;
const Promise = require('bluebird');
const Stats = require('./Stats');
const hasCallback = require('./utils').hasCallback;
const promisifyIfFunction = require('./utils').promisifyIfFunction;
const globalStats = require('./globalStats');
const consts = require('./consts');
const Circuit = require('./Circuit');
Expand All @@ -21,7 +21,9 @@ const defaultOptions = {
timeout: 15000,
healthCheckInterval: 5000,
healthCheck: undefined,
fallback: undefined
fallback: undefined,
isFunction: false,
isPromise: false
};

class Brakes extends EventEmitter {
Expand Down Expand Up @@ -51,9 +53,12 @@ class Brakes extends EventEmitter {
globalStats.register(this);
}

const isPromise = this._opts.isPromise;
const isFunction = this._opts.isFunction;

// check if health check is in options
if (this._opts.healthCheck) {
this.healthCheck(this._opts.healthCheck);
this.healthCheck(this._opts.healthCheck, isPromise, isFunction);
}

// create a master circuit
Expand All @@ -63,7 +68,7 @@ class Brakes extends EventEmitter {

// check if fallback is in options
if (this._opts.fallback) {
this.fallback(this._opts.fallback);
this.fallback(this._opts.fallback, isPromise, isFunction);
}
}

Expand Down Expand Up @@ -154,21 +159,16 @@ class Brakes extends EventEmitter {
Allow user to pass a function to be used as a health check,
to close the circuit if the function succeeds.
*/
healthCheck(func) {
if (hasCallback(func)) {
this._healthCheck = Promise.promisify(func);
}
else {
this._healthCheck = func;
}
healthCheck(func, isPromise, isFunction) {
this._healthCheck = promisifyIfFunction(func, isPromise, isFunction);
}

/*
Allow user to pass function to be used as a fallback
*/
fallback(func) {
fallback(func, isPromise, isFunction) {
if (this._masterCircuit) {
this._masterCircuit.fallback(func);
this._masterCircuit.fallback(func, isPromise, isFunction);
}
else {
throw new Error(consts.NO_FUNCTION);
Expand Down
20 changes: 5 additions & 15 deletions lib/Circuit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const EventEmitter = require('events').EventEmitter;
const Promise = require('bluebird');
const hasCallback = require('./utils').hasCallback;
const promisifyIfFunction = require('./utils').promisifyIfFunction;
const TimeOutError = require('./TimeOutError');
const CircuitBrokenError = require('../lib/CircuitBrokenError');
const consts = require('./consts');
Expand Down Expand Up @@ -40,15 +40,10 @@ class Circuit extends EventEmitter {
this._opts = Object.assign({}, defaultOptions, options);
this._this = this._opts.this || this;

if (hasCallback(main)) {
this._serviceCall = Promise.promisify(main);
}
else {
this._serviceCall = main;
}
this._serviceCall = promisifyIfFunction(main, this._opts.isPromise, this._opts.isFunction);

if (fallback) {
this.fallback(fallback);
this.fallback(fallback, this._opts.isPromise, this._opts.isFunction);
}
}

Expand Down Expand Up @@ -114,13 +109,8 @@ class Circuit extends EventEmitter {
});
}

fallback(func) {
if (hasCallback(func)) {
this._fallback = Promise.promisify(func);
}
else {
this._fallback = func;
}
fallback(func, isPromise, isFunction) {
this._fallback = promisifyIfFunction(func, isPromise, isFunction);
}
}

Expand Down
15 changes: 15 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

const Promise = require('bluebird');

const callbacks = ['cb', 'callback', 'callback_', 'done'];

function hasCallback(fn) {
Expand All @@ -8,6 +10,18 @@ function hasCallback(fn) {
return callbacks.indexOf(callbackCandidate) > -1;
}

function promisifyIfFunction(fn, isPromise, isFunction) {
if (isPromise) {
return fn;
}

if (isFunction || hasCallback(fn)) {
return Promise.promisify(fn);
}

return fn;
}

/*
* Return a list arguments for a function
*/
Expand Down Expand Up @@ -94,6 +108,7 @@ function mapToHystrixJson(json) {
module.exports = {
callbacks,
hasCallback,
promisifyIfFunction,
getFnArgs,
mapToHystrixJson
};
8 changes: 6 additions & 2 deletions test/Brakes.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ const defaultOptions = {
timeout: 15000,
healthCheckInterval: 5000,
healthCheck: undefined,
fallback: undefined
fallback: undefined,
isFunction: false,
isPromise: false
};

const noop = function noop(foo, err, cb) {
Expand Down Expand Up @@ -159,7 +161,9 @@ describe('Brakes Class', () => {
timeout: 100,
healthCheckInterval: 1000,
healthCheck: () => Promise.resolve(),
fallback: () => Promise.resolve()
fallback: () => Promise.resolve(),
isFunction: false,
isPromise: false
};
brake = new Brakes(noop, overrides);
expect(brake._opts).to.deep.equal(overrides);
Expand Down
33 changes: 33 additions & 0 deletions test/utils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,37 @@ describe('utils', () => {
});
});
});
describe('promisifyIfFunction', () => {
it('should return input if isPromise: true', () => {
// eslint-disable-next-line no-unused-vars
function cb(done) {}

expect(utils.promisifyIfFunction(cb, true)).to.be.equal(cb);
});

it('should return input promise', () => {
function cb() { return Promise.resolve(); }

expect(utils.promisifyIfFunction(cb, true)).to.be.equal(cb);
});

it('should promisify if isFunction: true, even if wrong name of argument', () => {
// eslint-disable-next-line no-unused-vars
function cb(foo) {}

const promisifyIfFunction = utils.promisifyIfFunction(cb, false, true);

// Hackish... Might only work with bluebird
expect(promisifyIfFunction.__isPromisified__).to.be.equal(true);
});

it('should promisify if is a callback', () => {
// eslint-disable-next-line no-unused-vars
function cb(done) {}

const promisifyIfFunction = utils.promisifyIfFunction(cb);

expect(promisifyIfFunction.__isPromisified__).to.be.equal(true);
});
});
});