Skip to content

Commit

Permalink
feat: allow multiple circuits to aggregate stats
Browse files Browse the repository at this point in the history
If a user creates multiple circuits in the same process, they should aggregate
their stats in the Hystrix stream.

Fixes: #125
Ref: #124
  • Loading branch information
lance committed Jan 30, 2018
1 parent 224c6ef commit 1b9e3c1
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 20 deletions.
39 changes: 19 additions & 20 deletions lib/hystrix-stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@
const stream = require('stream');
const hystrixFormatter = require('./hystrix-formatter');

// only use a single hystrix stream for all circuits
const hystrixStream = new stream.Transform({
objectMode: true
});

// The stats coming in should be already "Reduced"
function hystrixTransformer (stats, encoding, cb) {
const formattedStats = hystrixFormatter(stats);

// Need to take the stats and map them to the hystrix format
return cb(null, `{"data": ${JSON.stringify(formattedStats)}}\n\n`);
}

// Need a _transform() function to satisfy the protocol
hystrixStream._transform = hystrixTransformer;
hystrixStream.resume();

/**
* @class
* <p>
Expand Down Expand Up @@ -35,34 +52,16 @@ class HystrixStats {
objectMode: true
});

// Need a _read() function to satisfy the protocol
this._readableStream._read = () => {};
this._readableStream.resume();

this._hystrixStream = new stream.Transform({
objectMode: true
});

// Need a _transform() function to satisfy the protocol
this._hystrixStream._transform = this._hystrixTransformer;
this._hystrixStream.resume();

this._readableStream.pipe(this._hystrixStream);
}

// The stats coming in should be already "Reduced"
_hystrixTransformer (stats, encoding, cb) {
const formattedStats = hystrixFormatter(stats);

// Need to take the stats and map them to the hystrix format
return cb(null, `data: ${JSON.stringify(formattedStats)}\n\n`);
this._readableStream.pipe(hystrixStream);
}

/**
A convenience function that returns the hystrxStream
*/
getHystrixStream () {
return this._hystrixStream;
return hystrixStream;
}

// This will take the stats data from the listener and
Expand Down
33 changes: 33 additions & 0 deletions test/hystrix-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';

const test = require('tape');
const cb = require('../');
const { passFail } = require('./common');

test('A circuit should provide stats to a hystrix compatible stream', t => {
t.plan(2);
const circuitOne = cb(passFail, {
rollingCountTimeout: 100,
rollingCountBuckets: 1,
name: 'circuit one'
});
const circuitTwo = cb(passFail, {
rollingCountTimeout: 100,
rollingCountBuckets: 1,
name: 'circuit two'
});
const stream = circuitOne.hystrixStats.getHystrixStream();
let circuitOneStatsSeen = false;
let circuitTwoStatsSeen = true;
stream.on('data', blob => {
const obj = JSON.parse(blob);
if (obj.data.name === 'circuit one') circuitOneStatsSeen = true;
else if (obj.data.name === 'circuit two') circuitTwoStatsSeen = true;
});
circuitOne.fire(10).then(_ => circuitTwo.fire(10)).then(_ => {
console.log('checking');
t.ok(circuitOneStatsSeen, 'circuit one stats seen');
t.ok(circuitTwoStatsSeen, 'circuit two stats seen');
t.end();
});
});

0 comments on commit 1b9e3c1

Please sign in to comment.