-
Notifications
You must be signed in to change notification settings - Fork 96
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
Conversation
daaf6e8
to
f1cebbd
Compare
There was a problem hiding this 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) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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...
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough.
There was a problem hiding this comment.
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!
There was a problem hiding this 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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough.
c3a735b
to
5865766
Compare
.map(metrics::get) | ||
.map(LogicalMetric::getTemplateDruidQuery) | ||
.reduce(TemplateDruidQuery::merge) | ||
.orElseGet(() -> { |
There was a problem hiding this comment.
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);
}
There was a problem hiding this comment.
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); | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
feada28
to
df01060
Compare
👍 |
Simplified calls in maker code so as to not use TDQ where unnecessary
Streamified for loop for making arithmetic operations