Skip to content

Instantly share code, notes, and snippets.

@hijaq
Last active July 31, 2018 01:53
Show Gist options
  • Save hijaq/540796b81a6e5d0302a876a62a0eb184 to your computer and use it in GitHub Desktop.
Save hijaq/540796b81a6e5d0302a876a62a0eb184 to your computer and use it in GitHub Desktop.
const { commandFactory: CommandFactory } = require('hystrixjs');
/**
* Initializes and returns a circuit breaker
* @param {function} fn Function to execute
* @param {object} opts Hystrix options
* @property {number} opts.timeout Timeout for request
* @property {function} opts.errorHandler Function to validate if the error response from the service is an actual error
* @property {function} opts.fallbackTo Function, which will be executed if the request fails. The function will be called with the error as the 1st argument and an array of the original args as the 2nd argument
* @property {number} opts.circuitBreakerSleepWindowInMilliseconds How long the circuit breaker should stay opened, before allowing a single request to test the health of the service
* @property {number} opts.circuitBreakerRequestVolumeThreshold Minimum number of requests in a rolling window that needs to be exceeded, before the circuit breaker will bother at all to calculate the health
* @property {boolean} opts.circuitBreakerForceOpened Force this circuit breaker to be always opened
* @property {boolean} opts.circuitBreakerForceClosed Force this circuit breaker to be always closed
* @property {number} opts.circuitBreakerErrorThresholdPercentage Error percentage threshold to trip the circuit
* @property {number} opts.statisticalWindowLength Length of the window to keep track of execution counts metrics (success, failure)
* @property {number} opts.statisticalWindowNumberOfBuckets Number of buckets within the statistical window
* @property {number} opts.percentileWindowNumberOfBuckets Number of buckets within the percentile window
* @property {number} opts.percentileWindowLength Length of the window to keep track of execution times
* @property {number} opts.requestVolumeRejectionThreshold Maximum number of concurrent requests, which can be executed. Defaults to 0, i.e. no limitation
* @returns {object} Circuit Breaker service
*/
const breaker = (fn, opts = {}) => {
const cmd = CommandFactory.getOrCreate(`fetch-${Date.now()}-${~~(Math.random() * 1000)}}`).run(fn);
if (typeof opts.timeout === 'number') {
cmd.timeout(opts.timeout);
}
if (typeof opts.errorHandler === 'function') {
cmd.errorHandler(opts.errorHandler);
}
if (typeof opts.fallbackTo === 'function') {
cmd.fallbackTo(opts.fallbackTo);
}
if (typeof opts.circuitBreakerSleepWindowInMilliseconds === 'number') {
cmd.circuitBreakerSleepWindowInMilliseconds(opts.circuitBreakerSleepWindowInMilliseconds);
}
if (typeof opts.circuitBreakerRequestVolumeThreshold === 'number') {
cmd.circuitBreakerRequestVolumeThreshold(opts.circuitBreakerRequestVolumeThreshold);
}
if (typeof opts.circuitBreakerForceOpened === 'boolean') {
cmd.circuitBreakerForceOpened(opts.circuitBreakerForceOpened);
}
if (typeof opts.circuitBreakerForceClosed === 'boolean') {
cmd.circuitBreakerForceClosed(opts.circuitBreakerForceClosed);
}
if (typeof opts.circuitBreakerErrorThresholdPercentage === 'number') {
cmd.circuitBreakerErrorThresholdPercentage(opts.circuitBreakerErrorThresholdPercentage);
}
if (typeof opts.statisticalWindowLength === 'number') {
cmd.statisticalWindowLength(opts.statisticalWindowLength);
}
if (typeof opts.statisticalWindowNumberOfBuckets === 'number') {
cmd.statisticalWindowNumberOfBuckets(opts.statisticalWindowNumberOfBuckets);
}
if (typeof opts.percentileWindowLength === 'number') {
cmd.percentileWindowLength(opts.percentileWindowLength);
}
if (typeof opts.requestVolumeRejectionThreshold === 'number') {
cmd.requestVolumeRejectionThreshold(opts.requestVolumeRejectionThreshold);
}
return cmd.build();
};
/**
* Initializes and returns hystrixfied fetch
* @param {object} fetch Fetch
* @param {object} cbopts HystrixJS options
*/
const init = (fetch, cbopts) => {
const cmd = breaker(fetch, cbopts);
return (uri, opts) => cmd.execute(uri, opts);
};
module.exports = init;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment