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

Support int typed aggregations #696

Merged
merged 19 commits into from
Jul 17, 2019

Conversation

colincadams
Copy link
Contributor

This makes Aggregation a factory of AggregationData, using the type of the underlying measure to determine which value type to use.

fixes #565

Currently just a first pass, looking for feedback on the approach that we started discussing in #565.

@colincadams colincadams force-pushed the aggregate-ints branch 2 times, most recently from 5c78be8 to 7e2474f Compare June 27, 2019 03:08
@reyang
Copy link
Contributor

reyang commented Jun 27, 2019

@lzchen please help to review.

Copy link
Contributor

@songy23 songy23 left a comment

Choose a reason for hiding this comment

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

Looks good overall, please fix lint.

opencensus/stats/aggregation.py Outdated Show resolved Hide resolved
@@ -51,8 +35,7 @@ class BaseAggregation(object):
:param aggregation_type: represents the type of this aggregation

"""
def __init__(self, buckets=None, aggregation_type=Type.NONE):
self._aggregation_type = aggregation_type
def __init__(self, buckets=None):
self._buckets = buckets or []

@property
Copy link
Contributor

@lzchen lzchen Jun 28, 2019

Choose a reason for hiding this comment

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

You still have an aggregation_type property. As well remove the param comment.

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 ended up removing BaseAggregation altogether, per @c24t's comments.

@@ -78,16 +61,24 @@ class SumAggregation(BaseAggregation):
:param aggregation_type: represents the type of this aggregation
Copy link
Contributor

@lzchen lzchen Jun 28, 2019

Choose a reason for hiding this comment

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

IMO, I would include a get_metric_type(measure) method in BaseAggregation with no implementation to let developers know that aggregations should implement this (there might be new kinds of aggregations)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same as above.

@@ -101,16 +92,16 @@ class CountAggregation(BaseAggregation):
:param aggregation_type: represents the type of this aggregation
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix param comments

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

:class:`opencensus.metrics.export.value.ValueDouble` or
:class:`opencensus.metrics.export.value.ValueLong`
:param value_type: the type of value to be used when creating a point
:type sum_data: meh
Copy link
Contributor

Choose a reason for hiding this comment

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

meh?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

loll 🤸‍♂

@@ -78,16 +61,24 @@ class SumAggregation(BaseAggregation):
:param aggregation_type: represents the type of this aggregation
Copy link
Contributor

@lzchen lzchen Jun 28, 2019

Choose a reason for hiding this comment

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

Nit: Fix "Sum Aggregation DESCRIBES" in comments

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@lzchen
Copy link
Contributor

lzchen commented Jun 28, 2019

This is great! The factory design is very slick. Just a couple of comments and should be good to go!

Copy link
Member

@c24t c24t left a comment

Choose a reason for hiding this comment

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

This is a huge improvement, great that you were able to remove aggregation.aggregation_data and aggregation.aggregation_type and get_metric_type.

Besides @lzchen's comments I'd ask that you also remove BaseAggregation, or at least move buckets down to the distribution class.

@@ -51,8 +35,7 @@ class BaseAggregation(object):
:param aggregation_type: represents the type of this aggregation

"""
def __init__(self, buckets=None, aggregation_type=Type.NONE):
self._aggregation_type = aggregation_type
def __init__(self, buckets=None):
Copy link
Member

Choose a reason for hiding this comment

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

While you're in here: I don't see any reason for buckets to be on BaseAggregation, it looks like an odd choice from the first implementation (#149) that never got cleaned up. Since aggregation_type is gone now I recommend scrapping this whole class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, just removed the class.

@@ -52,16 +52,21 @@ def to_point(self, timestamp):
raise NotImplementedError # pragma: NO COVER


class SumAggregationDataFloat(BaseAggregationData):
class SumAggregationData(BaseAggregationData):
Copy link
Member

Choose a reason for hiding this comment

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

Why the decision to make value_type an instance attr instead of keeping separate aggregation classes for each value type here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Initially, I had this private class with value_type and then bound classes like:

SumAggregationDataFloat = functools.partial(SumAggregationData, value_type=value.ValueDouble)
SumAggregationDataInt = functools.partial(SumAggregationData, value_type=value.ValueInt)

But then in SumAggregation.new_aggregation_data, we needed an additional set of conditionals to check the type of the measure or metric and decide which to use. Instead doing it this way, we just need the one set of conditionals in .get_metric_type which we need anyway, and can reuse MetricDescriptor.to_type_class. It seemed a little cleaner, but really it isn't that different.

We could also duplicate the classes entirely, instead of the functools.partial, but that seemed unnecessary.

I guess the other option is to force the user to decide and provide Int or Float, but since we can determine it that seems easier and less error prone.

@lzchen
Copy link
Contributor

lzchen commented Jul 2, 2019

Also fixes [#679]

@@ -52,16 +52,21 @@ def to_point(self, timestamp):
raise NotImplementedError # pragma: NO COVER


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 BaseAggregationData class seems a little odd to me as well, each implementation supplies aggregation_data upon construction but then doesn't update it, and stores there data in a separate instance variable that they update and return.

Is there a reason for this class to exist?

Copy link
Member

Choose a reason for hiding this comment

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

Not that I can tell, besides to show that aggregations should implement to_point, but in that case there should be an unimplemented add_sample in the class too.

In any case it looks like you can lose the aggregation_data attr and property.

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 just removed BaseAggregationData entirely

"""Get the MetricDescriptorType for the metric produced by this
aggregation and measure.
"""
if isinstance(measure, measure_module.MeasureInt):
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't have strong opinion here, it seems a more "Pythonic" style is:

        if isinstance(measure, measure_module.MeasureInt):
            return MetricDescriptorType.CUMULATIVE_INT64
        if isinstance(measure, measure_module.MeasureFloat):
            return MetricDescriptorType.CUMULATIVE_DOUBLE
        raise ValueError

Up to you.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, surprised the linter didn't yell about this (or maybe it was a warning I didn't see 😁)

Copy link
Member

@c24t c24t left a comment

Choose a reason for hiding this comment

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

LGTM after removing the attr from BaseAggregationData (or the whole class). Please also add a note to the changelog.

Copy link
Contributor

@reyang reyang left a comment

Choose a reason for hiding this comment

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

This is a big improvement, thank you @colincadams!

@c24t c24t merged commit 0d00458 into census-instrumentation:master Jul 17, 2019
@colincadams colincadams deleted the aggregate-ints branch July 17, 2019 23:39
@colincadams
Copy link
Contributor Author

Thanks all! And thanks for updating the changelog @c24t, totally forgot!

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

Successfully merging this pull request may close these issues.

Support int export for sum and lastvalue aggregations
6 participants