all files / src/ breaker.js

14.81% Statements 4/27
50% Branches 2/4
0% Functions 0/5
15.38% Lines 4/26
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58                                                                                                            
const { commandFactory } = require('hystrixjs');
 
const promisify = require('util.promisify');
const callbackify = require('util').callbackify || function (promiser) {
    return function (...args) {
        const callback = args.pop();
        promiser.apply(this, args).then(
            result => callback(null, result),
            error => callback(error)
        );
    };
};
 
module.exports = (redis, options) => {
    const service = promisify((command_obj, callback) => {
        command_obj.callback = callback;
    });
 
    const fallback = promisify((error, [command_obj], callback) => {
        command_obj.command = command_obj.callback = null;
        callback(error);
    });
 
    const breaker = commandFactory.getOrCreate(options.name)
        .circuitBreakerErrorThresholdPercentage(options.errorThreshold)
        .timeout(options.timeout)
        .run(service)
        .circuitBreakerRequestVolumeThreshold(options.volumeThreshold)
        .requestVolumeRejectionThreshold(options.rejectionThreshold)
        .circuitBreakerSleepWindowInMilliseconds(options.sleepWindow)
        .statisticalWindowLength(options.windowLength)
        .statisticalWindowNumberOfBuckets(options.windowBuckets)
        .fallbackTo(fallback)
        .build();
 
    const { createClient } = redis;
 
    redis.createClient = function () {
        const client = createClient.apply(this, arguments);
 
        const  { internal_send_command } = client;
 
        client.internal_send_command = function (command_obj) {
            const { command, callback = function () {} } = command_obj;
 
            if (!command) return true;
 
            callbackify(breaker.execute).call(breaker, command_obj, callback);
 
            return internal_send_command.call(this, command_obj);
        };
 
        return client;
    };
 
    return redis;
};