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

Added getMetricField to LogicalMetric #124

Merged
merged 4 commits into from
Dec 20, 2016
Merged

Conversation

michael-mclawhorn
Copy link
Contributor

Simplified calls in maker code so as to not use TDQ where unnecessary
Streamified for loop for making arithmetic operations

Copy link
Collaborator

@cdeszaq cdeszaq left a comment

Choose a reason for hiding this comment

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

Some concerns about change management, but otherwise the changes look fine.

* @param name Name of the metric to fetch the template druid query from
* @return The template druid query of the metric
*/
protected TemplateDruidQuery getDependentQuery(String name) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We can't just remove this, since it was protected and in a class that we intended to be extended. We need to @Deprecate it instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

boo. Ok.

return names.stream()
.map(metrics::get)
.map(LogicalMetric::getTemplateDruidQuery)
.reduce(TemplateDruidQuery::merge)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does merge handle null correctly? I know we're collapsing the error check to the end of this stream (which I'm a fan of), but I just want to make sure that the merge will still be working correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The previous implementation calls names.size first and thus blows up on names being null.
Similarly, getDependentQuery wasn't nullsafeing on it's MetricDictionary.get().getTemplateDruidQuery()
So the only open question is whether reduce with a binary function does the thing it's spec says it does.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I didn't look at reduce's contract, so if it's protecting us, we're good 😄

@@ -187,7 +170,7 @@ protected TemplateDruidQuery getMergedQuery(List<String> names) {
*/
protected PostAggregation getNumericField(String fieldName) {
// Get the field
MetricField field = getDependentQuery(fieldName).getMetricField(fieldName);
MetricField field = metrics.get(fieldName).getMetricField();
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is not the same semantics, is it? In the previous code, it was retrieving an aggregation with a specific name from a metric with that name. Admittedly, the previous code had many assumptions, and I think the new semantics are better, but we should be at least a little careful here, since this is a protected method, meaning that others could be relying on it...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The previous method call did:
foo = metrics.get(fieldName)
bar = return foo.getTemplateDruidQuery
bar.getMetricField(fieldName)

How is this not the same?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ahh, I see. Makes sense then. Clearly, the previous code was worse, since it was harder to trace 😉

@@ -212,7 +195,7 @@ protected PostAggregation getNumericField(String fieldName) {
*/
protected PostAggregation getSketchField(String fieldName) {
// Get the field
MetricField field = getDependentQuery(fieldName).getMetricField(fieldName);
MetricField field = metrics.get(fieldName).getMetricField();
Copy link
Collaborator

Choose a reason for hiding this comment

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

ditto my comments on semantic changes

@@ -61,15 +61,13 @@ public AggregationAverageMaker(MetricDictionary metrics, ZonelessTimeGrain inner
@Override
protected LogicalMetric makeInner(String metricName, List<String> dependentMetrics) {
// Get the Metric that is being averaged over
String dependantMetricName = dependentMetrics.get(0);
TemplateDruidQuery innerDependentQuery = getDependentQuery(dependantMetricName);
MetricField sourceMetric = innerDependentQuery.getMetricField(dependantMetricName);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this really the only maker in which we were doing 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.

the vast majority of our makes are aggregation makers.
Of the post aggregation makers, sketch makers access this type of logic via the 'getSketchField' method in the base MetricMaker class.
ArithmeticMaker goes through the 'getNumericField' method in the MetricMaker class.
That just leaves daily averages. We have less post aggregation type variety than you might suspect.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Fair enough.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yay for less variety than you might suspect!

Copy link
Collaborator

@cdeszaq cdeszaq left a comment

Choose a reason for hiding this comment

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

Just the call-out of the deprecation in the ChangeLog. Otherwise, this looks good. 👍

@@ -61,15 +61,13 @@ public AggregationAverageMaker(MetricDictionary metrics, ZonelessTimeGrain inner
@Override
protected LogicalMetric makeInner(String metricName, List<String> dependentMetrics) {
// Get the Metric that is being averaged over
String dependantMetricName = dependentMetrics.get(0);
TemplateDruidQuery innerDependentQuery = getDependentQuery(dependantMetricName);
MetricField sourceMetric = innerDependentQuery.getMetricField(dependantMetricName);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Fair enough.

.map(metrics::get)
.map(LogicalMetric::getTemplateDruidQuery)
.reduce(TemplateDruidQuery::merge)
.orElseGet(() -> {
Copy link
Contributor

Choose a reason for hiding this comment

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

What you actually want to use here is orElseThrow:

.orElseThrow(() -> {
          String message = "At least 1 name is needed to merge aggregations";
          LOG.error(message);
          return new IllegalArgumentException(message);
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah, yes, that's the one. I knew there was something like that...

String message = "At least 1 name is needed to merge aggregations";
LOG.error(message);
throw new IllegalArgumentException(message);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this bracket indented correctly? Typically, when the opening of a lambda is on the same line as a method, I put the closing bracket on the same line as the closing parens. i.e.:

  method(() -> {
      doStuf();
  });

and the closing bracket is on its own line only if the start of the lambda is on its own line:

method(
          () -> {
              doStuf();
          }
);

I don't have a strong opinion either way, I just wanted to know if we had a convention around this.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's not wrong, just a little different. I think all of the options are pretty much equal, though I do like the more compressed form of stacking things where it's obvious what's closing and isn't stacked too deep if I think hard about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Autoformat thinks that the closure shouldn't be double indented because it's a sub block not an argument line continuation. What do you think of what I'm about to post?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's fine.

@@ -187,7 +185,7 @@ protected TemplateDruidQuery getMergedQuery(List<String> names) {
*/
protected PostAggregation getNumericField(String fieldName) {
// Get the field
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment is now redundant.

Simplified calls in maker code so as to not use TDQ where unnecessary
Streamified for loop for making arithmetic operations
Tweaked indentation.
@archolewa
Copy link
Contributor

👍

@cdeszaq cdeszaq merged commit c71725d into master Dec 20, 2016
@cdeszaq cdeszaq deleted the RefactorMetricFieldAccessor branch December 20, 2016 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants