Skip to content

Commit

Permalink
Merge pull request #61 from SimenB/is-promise
Browse files Browse the repository at this point in the history
Add isPromise
  • Loading branch information
awolden committed Nov 15, 2016
2 parents 919bbc8 + 96f248d commit 3f7728a
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 30 deletions.
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);
});
});
});

0 comments on commit 3f7728a

Please sign in to comment.