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

fix(#13): Fix memory when systemStats are enabled #14

Merged
merged 4 commits into from
Aug 21, 2017

Conversation

senzzzi
Copy link
Contributor

@senzzzi senzzzi commented May 4, 2017

  • Fixed loop when systemStats are enabled
  • Added a non aggregated stats buffer to send this metrics
  • Functions that are exposed in the client object didn't change at all
    so it won't break anything
  • Added tests for new scenarios

- Fixed loop when systemStats are enabled
- Added a non aggregated stats buffer to send this metrics
- Functions that are exposed in the client object didn't change at all
  so it won't break anything
- Added tests for new scenarios
@miguelcnf
Copy link
Contributor

@senzzzi can you check the failing tests and the conflicts please?

Copy link
Contributor

@miguelcnf miguelcnf left a comment

Choose a reason for hiding this comment

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

Left a few comments. There's some things I'd like to see changed mostly:

  • Not mix test concerns between application and stats metrics
  • Not use boolean argument flags (I know some of that code was already there)
  • Remove logic/naming for aggregated stats metrics

Thanks for your work on this @senzzzi

// When
victim.aggregatedPut('my_metric1', 1, 'avg', 60);
victim.aggregatedPut('my_metric2', 1, 'avg', 60);

// Then
function onResponse(lines) {
httpsServer.stop();
if (counter === 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The tests are failing on this logic.

The order of the responses is not deterministic.

I think it's better and easier to split test concerns, as in test sending of application and system metrics in different tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I get it, I will update it :)

@@ -1,5 +1,7 @@
'use strict';

//jshint latedef: nofunc
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the reason for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We have a circular dependency on the functions we are using.. It does not allow the function declaration after being called.

lib/client.js Outdated
* @param aggregationFreq The aggregation frequency with which metric was aggregated.
* @param parameters An object with metric para meters: tags, agg, aggFreq, namespace and timestamp.
*/
function putMetric(self, metricTypeConf, name, value, aggregation, aggregationFreq, parameters, isStats) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Although it is quite present in this codebase, I'm not a super fan of the 'boolean argument to change behaviour' pattern - maybe we can can create a new putStatsMetric instead?

See the putAggregatedMetric and putNonAggregatedMetric as an example of this.

System metrics are also never aggregated so I think we really need to treat them differently.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can change the behaviour if you want. I chose this way, because the function that the client exposes is strictly the same but we can call it saying it's a stats metrics without having to repeat code..

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes I'd prefer that. We can extract the common code to it's own function and re-use it on both functions.

lib/client.js Outdated
self.logger.debug(stringToLogHeader + stringToLog);
}
if (self.nonAggregatedStatsBuffer.bufferSize > 0) {
self.logger.debug('Flushing metrics (non aggregated): ' + self.nonAggregatedStatsBuffer.buffer);
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe change to 'Flushing stats metrics: ' + ... as stats metrics will never be aggregated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

lib/client.js Outdated
self.logger.debug('Flushing metrics (non aggregated): ' + self.nonAggregatedStatsBuffer.buffer);
}

//in case we need to send aggregated stats metrics, add code here
Copy link
Contributor

Choose a reason for hiding this comment

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

You can remove this comment since stats metrics are never going to be aggregated.

}

/**
* Logs all the metrics to the logger
Copy link
Contributor

Choose a reason for hiding this comment

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

Wrong jsdoc.

lib/client.js Outdated
}
}

//in case we need to send aggregated stats metrics, add code here
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove

lib/client.js Outdated
*
* @param self A self client instance.
* @param metricLines The metrics, in valid line protocol, to push to the buffer.
* @param isMetricAggregated A boolean state if metrics are aggregated.
Copy link
Contributor

Choose a reason for hiding this comment

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

Stats metrics will never be aggregated.

lib/client.js Outdated
targetBuffer.buffer += metricLines;
targetBuffer.bufferSize++;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe flush if the stats buffer is over capacity? It's probably not something that's going to happen frequently since the metric buffers will trigger a flush on all buffers much more often but the check isn't that expensive so.

Copy link
Contributor Author

@senzzzi senzzzi May 10, 2017

Choose a reason for hiding this comment

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

Well, that is exactly the reason we are doing this fix. When we call the flush function if the buffer is "full" (independent of the reason/threshold), it will call again the function to put the stats metrics in the buffer and so on and so on... I'd rather have another interval (smaller than the timeout to flush the other metrics) to flush the stats metrics.

lib/client.js Outdated
@@ -334,9 +476,17 @@ function putRaw(self, metric, value, parameters, isMetricAggregated) {
}

if (!isMetricAggregated) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is why I'm really not a fan of the boolean argument flags.

The code becomes very unclear to follow, maybe you could refactor into different methods?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

@jmtavares jmtavares merged commit 0ba2710 into statful:master Aug 21, 2017
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