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

Addition of streaming hystrix data. #41

Merged
merged 2 commits into from
Apr 5, 2017

Conversation

lholmquist
Copy link
Member

@lholmquist lholmquist commented Mar 31, 2017

DO NOT MERGE - this is a WIP for #39

I've added a Class, HystrixStats, which produces a stream of the hystrix metrics.

A circuit breaker will register with this class during the creation of a circuit breaker, https://github.com/lholmquist/opossum/blob/status-stream-data/lib/circuit.js#L101 so for every snapshot event emitted, the stats stream is updated.

I'm storing the instance of the circuit that is passed in, in a WeakMap so the hystrix event stream can get a handle on it to give me the circuits name, group, etc..

@coveralls
Copy link

coveralls commented Mar 31, 2017

Coverage Status

Coverage decreased (-0.5%) to 98.374% when pulling 81412f1 on lholmquist:status-stream-data into 7bb3931 on bucharest-gold:master.

Copy link
Member

@lance lance left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize this is just your initial pass. Just providing some suggestions.

lib/circuit.js Outdated
@@ -93,6 +94,9 @@ class CircuitBreaker extends EventEmitter {
if (this.options.cache) {
CACHE.set(this, undefined);
}

// Register this instance of the circuit breaker with the hystrix stats listener
hystrixStats.register(this[STATUS]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With my latest push, this should be this[STATUS].stats. That will return an Object that has the properties you can see here. It represents the cumulative data for each event over the entire window.

function hystrixFormatter (stats) {
const json = {};
json.type = 'HystrixCommand';
json.name = 'ola';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The circuit breaker now has a name property that you can use for this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if i can get access to this information currently. Since the Status object emits the snapshot event, i only get the stats data during that event. maybe the Circuit class should emit the event(which i'm not sure about), or we add some metadata to the stats object that gets emitted during that snapshot event

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`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't hystrixFormatter already returning JSON?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it does, this is turning it into a string for the event stream

// Register the instance of a circuit to listen for a snapshot event
// during that event, call the hystrixSnapshotListener to do the stream stuff
register (circuitInstance) {
circuitInstance.on('snapshot', this._hystrixSnapshotListener.bind(this));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently it's the Status object that emits snapshot. That could change if you think it's better suited in CircuitBreaker, but I think it would be unnecessary indirection. It would mean that the circuit breaker listens to the status object for snapshot events and just propagates them to the client.

@lholmquist lholmquist force-pushed the status-stream-data branch 2 times, most recently from a151bfd to 1284d9b Compare April 3, 2017 15:04
@coveralls
Copy link

coveralls commented Apr 3, 2017

Coverage Status

Coverage decreased (-0.5%) to 98.367% when pulling 1284d9b on lholmquist:status-stream-data into 9ba4dfc on bucharest-gold:master.

@lholmquist lholmquist force-pushed the status-stream-data branch 2 times, most recently from 235d027 to 6401e0b Compare April 3, 2017 17:39
@coveralls
Copy link

coveralls commented Apr 3, 2017

Coverage Status

Coverage decreased (-0.6%) to 98.79% when pulling 6401e0b on lholmquist:status-stream-data into 3619678 on bucharest-gold:master.

@coveralls
Copy link

coveralls commented Apr 3, 2017

Coverage Status

Coverage decreased (-0.6%) to 98.79% when pulling 6401e0b on lholmquist:status-stream-data into 3619678 on bucharest-gold:master.

json.rollingCountFallbackMissing = 0;
json.rollingCountFallbackRejection = 0;
json.rollingCountFallbackSuccess = 0;
json.rollingCountResponsesFromCache = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use circuit.stats.cacheHits here.

json.latencyTotal = { '0': 0, '25': 0, '50': 0, '75': 0, '90': 0, '95': 0, '99': 0, '99.5': 0, '100': 0 };
json.propertyValue_circuitBreakerRequestVolumeThreshold = 5;
json.propertyValue_circuitBreakerSleepWindowInMilliseconds = 5000;
json.propertyValue_circuitBreakerErrorThresholdPercentage = 50;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use circuit.options to get this value as well as the previous two

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that last property i think i found in the options, but what would those other 2 be, the rollingCountTimeout and buckets?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lholmquist circuitBreakerSleepWindowInMilliseconds should be our options.resetTimeout. I guess we don't measure request volume, so we don't have a property for it. :)

json.propertyValue_circuitBreakerRequestVolumeThreshold = 5;
json.propertyValue_circuitBreakerSleepWindowInMilliseconds = 5000;
json.propertyValue_circuitBreakerErrorThresholdPercentage = 50;
json.propertyValue_circuitBreakerForceOpen = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have functions to force open/closed a circuit. Maybe we should add an issue for the circuit to keep track of this so it can be reported.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that sounds like a good idea

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i've created an issue #46

json.propertyValue_circuitBreakerErrorThresholdPercentage = 50;
json.propertyValue_circuitBreakerForceOpen = false;
json.propertyValue_circuitBreakerForceClosed = false;
json.propertyValue_circuitBreakerEnabled = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use circuit.closed here, maybe? I'm not sure if this stat is supposed to reflect the current state of the circuit breaker, or if with Hystrix, a user could enable/disable a circuit.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking at what the brakes library is doing for this value, they have it hard coded to true and have a comment about it being "not reported"

I can check the java lib to see what they do with it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking at the java lib, its here: https://github.com/Netflix/Hystrix/blob/master/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandProperties.java#L69

The comment is "// Whether circuit breaker should be enabled.", so this makes me think it doesn't have to do with the circuits closed/open state, but if the circuit breaker should be used or not

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

json.propertyValue_circuitBreakerEnabled = true;
json.propertyValue_executionIsolationStrategy = 'THREAD';
json.propertyValue_executionIsolationThreadTimeoutInMilliseconds = 300;
json.propertyValue_executionTimeoutInMilliseconds = 300;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the circuit's options here as well.

json.propertyValue_executionIsolationSemaphoreMaxConcurrentRequests = 10;
json.propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests = 10;
json.propertyValue_metricsRollingStatisticalWindowInMilliseconds = 10000;
json.propertyValue_requestCacheEnabled = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here :)


// Register the instance of a circuit stats to listen for a snapshot event
// during that event, call the hystrixSnapshotListener to do the stream stuff
register (circuitInstance) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason to have this separated out? Couldn't the user just pass the circuit to the constructor, and this code could be executed there, no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currently the class is exported as a new instance, so you wouldn't be able to pass it along since the constructor is called while you require it.

I think i do like that better though, having the CircuitBreakers constructor calling new HystrixStats() and registering then, let me change that

@coveralls
Copy link

coveralls commented Apr 3, 2017

Coverage Status

Coverage decreased (-0.6%) to 98.79% when pulling 4a3b7f7 on lholmquist:status-stream-data into 3619678 on bucharest-gold:master.

@coveralls
Copy link

coveralls commented Apr 4, 2017

Coverage Status

Coverage decreased (-0.6%) to 98.79% when pulling 241509e on lholmquist:status-stream-data into 3619678 on bucharest-gold:master.

@coveralls
Copy link

coveralls commented Apr 5, 2017

Coverage Status

Coverage decreased (-0.6%) to 98.79% when pulling 48bfb97 on lholmquist:status-stream-data into 3619678 on bucharest-gold:master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.2%) to 99.194% when pulling 9ef1339 on lholmquist:status-stream-data into 3619678 on bucharest-gold:master.

1 similar comment
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.2%) to 99.194% when pulling 9ef1339 on lholmquist:status-stream-data into 3619678 on bucharest-gold:master.

@coveralls
Copy link

coveralls commented Apr 5, 2017

Coverage Status

Coverage decreased (-0.2%) to 99.194% when pulling 9f883a8 on lholmquist:status-stream-data into 3619678 on bucharest-gold:master.

@coveralls
Copy link

coveralls commented Apr 5, 2017

Coverage Status

Coverage decreased (-0.2%) to 99.194% when pulling 3352783 on lholmquist:status-stream-data into 3619678 on bucharest-gold:master.

@coveralls
Copy link

coveralls commented Apr 5, 2017

Coverage Status

Coverage decreased (-0.2%) to 99.194% when pulling c5c5261 on lholmquist:status-stream-data into 3619678 on bucharest-gold:master.

@coveralls
Copy link

coveralls commented Apr 5, 2017

Coverage Status

Coverage decreased (-0.2%) to 99.194% when pulling 8080ddc on lholmquist:status-stream-data into 3619678 on bucharest-gold:master.

@lholmquist lholmquist changed the title [WIP] first pass at adding in streaming hystrix data. will squash later Addition of streaming hystrix data. Apr 5, 2017
@@ -231,3 +231,11 @@ you create the breaker. E.g.
// Force opossum to use native JS promises
const breaker = circuitBreaker(readFile, { Promise: Promise });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm debating removing Fidelity from opossum, fwiw.

A stream is now provided using the circuit.hystrixStats.getHystrixStream method.
This stream can be easily turned into a SSE stream for use with a Hystrix Dashboard.
@lholmquist lholmquist merged commit fd8246a into nodeshift:master Apr 5, 2017
@ghost ghost removed the needs-review label Apr 5, 2017
@coveralls
Copy link

coveralls commented Apr 5, 2017

Coverage Status

Coverage decreased (-0.2%) to 99.194% when pulling fd8246a on lholmquist:status-stream-data into 3b3e309 on bucharest-gold:master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants