I'm not sure what you mean by "Using a map in an option."

For your second issue, the google docs around this show[1]:

Note that if you want to use a custom option in a package other than the
one in which it was defined, you must prefix the option name with the
package name, just as you would for type names. For example:

// foo.proto
import "google/protobuf/descriptor.proto";
package foo;
extend google.protobuf.MessageOptions {
  optional string my_option = 51234;
}

// bar.proto
import "foo.proto";
package bar;
message MyMessage {
  option (foo.my_option) = "Hello world!";
}


1: https://developers.google.com/protocol-buffers/docs/proto#customoptions


On Mon, Oct 29, 2018 at 5:19 PM Alex Amato <ajam...@google.com> wrote:

> Hi Robert and community, :)
>
> I was starting to code this up, but I wasn't sure exactly how to do some
> of the proto syntax. Would you mind taking a look at this doc
> <https://docs.google.com/document/d/1SB59MMVZXO0Aa6w0gf4m0qM4oYt4SiofDq3QxnpQaK4/edit?usp=sharing>
> and let me know if you know how to resolve any of these issues:
>
>    - Using a map in an option.
>    - Referring to string "constants" from other enum options in .proto
>    files.
>
> Please see the comments I have listed in the doc
> <https://docs.google.com/document/d/1SB59MMVZXO0Aa6w0gf4m0qM4oYt4SiofDq3QxnpQaK4/edit?usp=sharing>,
> and a few alternative suggestions.
> Thanks
>
> On Wed, Oct 24, 2018 at 10:08 AM Alex Amato <ajam...@google.com> wrote:
>
>> Okay. That makes sense. Using runtime validation and protos is what I was
>> thinking as well.
>> I'll include you as a reviewer in my PRs.
>>
>> As for the choice of a builder/constructor/factory. If we go with factory
>> methods/constructor then we will need a method for each metric type
>> (intCounter, latestInt64, ...). Plus, then I don't think we can have any
>> constructor parameters for labels, we will just need to accept a dictionary
>> for label keys+values like you say. This is because we cannot offer a
>> method for each URN and its combination of labels, and we should avoid such
>> static detection, as you say.
>>
>> The builder however, allows us to add a method for setting each label.
>> Since there are a small number of labels I think this should be fine. A
>> specific metric URN will have a specific set of labels which we can
>> validate being set. Any variant of this should use a different label (or a
>> new version in the label). Thus, the builder can give an advantage, making
>> it easier to set label values without needing to provide the correct key
>> for the label, when its set. You just need to call the correct method.
>>
>> Perhaps it might be best to leave this open to each SDK based on its
>> language style (Builder, Factory, etc.) , but make sure we use the
>> protos+runtime validation.
>>
>> On Wed, Oct 24, 2018 at 7:02 AM Robert Bradshaw <rober...@google.com>
>> wrote:
>>
>>> Thanks for bringing this to the list; it's a good question.
>>>
>>> I think the difficulty comes from trying to statically define a lists
>>> of possibilities that should instead be runtime values. E.g. we
>>> currently we're up to about a dozen distinct types, and having a
>>> setter for each is both verbose and not very extensible (especially
>>> replicated cross language). I'm not sure the set of possible labels is
>>> fixed either. Generally in the FnAPI we've been using shared constants
>>> for this kind of thing instead. (I was wary about the protos for the
>>> same reasons; it would be good to avoid leaking this through to each
>>> of the various SDKs.) The amount of static typing/validation one gets
>>> depends on how much logic you build into each of these methods (e.g.
>>> does it (almost?) always "metric" which is assumed to already be
>>> encoded correctly, or a specific type that has tradeoffs with the
>>> amount you can do generically (e.g. we have code that first loops over
>>> counters, then over distributions, then over gauges, and I don't think
>>> we want continue that pattern all M places for all N types)).
>>>
>>> I would probably lean towards mostly doing runtime validation here.
>>> Specifically, one would have a data file that defines, for each known
>>> URN, its type along with the set of permitted/expected/required
>>> labels. On construction a MonitoringInfo data point, one would provide
>>> a URN + value + labelMap, and optionally a type. On construction, the
>>> constructor (method, factory, whatever) would look up the URN to
>>> determine the type (or throw an error if it's both not known and not
>>> provided), which could be then used to fetch an encoder of sorts (that
>>> can go from value <-> proto encoding, possibly with some validation).
>>> If labels and/or annotations are provided and the URN is known, we can
>>> validate these as well.
>>>
>>> As for proto/enums vs. yaml, the former is nice because code
>>> generation comes for free, but has turned out to be much more verbose
>>> (both the definition and the use) and I'm still on the fence whether
>>> it's a net win.
>>>
>>> (Unfortunately AutoValue won't help much here, as the ultimate goal is
>>> to wrap a very nested proto OneOf, ideally with some validation.
>>> (Also, in Python, generally, having optional, named arguments makes
>>> this kind of builder pattern less needed.))
>>>
>>> On Wed, Oct 24, 2018 at 4:12 AM Kenneth Knowles <k...@apache.org> wrote:
>>> >
>>> > FWIW AutoValue will build most of that class for you, if it is as you
>>> say.
>>> >
>>> > Kenn
>>> >
>>> > On Tue, Oct 23, 2018 at 6:04 PM Alex Amato <ajam...@google.com> wrote:
>>> >>
>>> >> Hi Robert + beam dev list,
>>> >>
>>> >> I was thinking about your feedback in PR#6205, and agree that this
>>> monitoring_infos.py became a bit big.
>>> >>
>>> >> I'm working on the Java Implementation of this now, and want to
>>> incorporate some of these ideas and improve on this.
>>> >>
>>> >> I that that I should make something like a MonitoringInfoBuilder
>>> class. With a few methods
>>> >>
>>> >> setUrn
>>> >> setTimestamp
>>> >> setting the value (One method for each Type we support. Setting this
>>> will also set the type string)
>>> >>
>>> >> setInt64CounterValue
>>> >> setDoubleCounterValue
>>> >> setLatestInt64
>>> >> setTopNInt64
>>> >> setMonitoringDataTable
>>> >> setDistributionInt64
>>> >> ...
>>> >>
>>> >> setting labels (will set the key and value properly for the label)
>>> >>
>>> >> setPTransform(value)
>>> >> setPcollection(value)
>>> >> ...
>>> >>
>>> >>
>>> >> I think this will make building a metric much easier, you would just
>>> call the 4 methods and the .build(). These builders are common in Java. (I
>>> guess there is a similar thing way we could do in python? I'd like to go
>>> back and refactor that as well when I am done)
>>> >>
>>> >> -------------
>>> >>
>>> >> As for your other suggestion to define metrics in the proto/enum file
>>> instead of the yaml file. I am not too sure about the best strategy for
>>> this. My initial thoughts are:
>>> >>
>>> >> Make a proto extension allowing you to describe/define a
>>> MonitoringInfo's (the same info as the metric_definitions.yaml file):
>>> >>
>>> >> URN
>>> >> Type
>>> >> Labels required
>>> >> Annotations: Description, Units, etc.
>>> >>
>>> >> Make the builder read in that MonitoringInfo definision/description
>>> assert everything is set properly? I think this would be a decent data
>>> driven approach.
>>> >>
>>> >> I was wondering if you had something else in mind?
>>> >>
>>> >> Thanks
>>> >> Alex
>>> >>
>>> >>
>>>
>>

Reply via email to