Thanks for all the follow up comments! As I mentioned earlier, I am ok with adding overloads instead of using Materialized to specify the processor name. Seems this is what the majority of people prefers.
I am also +1 on Guozhang's suggestion to deprecate `static Joined#named()` and replace it with `static Joined#as` for consistency and to deprecate getter `Joined#name()` for removal and introduce `JoinedInternal` to access the name. @Guozhang: the vote is already up :) -Matthias On 1/17/19 2:45 PM, Guozhang Wang wrote: > Wow that's a lot of discussions in 6 days! :) Just catching up and sharing > my two cents here: > > 1. Materialized: I'm inclined to not let Materialized extending Named and > add the overload as well. All the rationales have been very well summarized > before. Just to emphasize on John's points: Materialized is considered as > the control object being leveraged by the optimization framework to > determine if the state store should be physically materialized or not. So > let's say if the user does not want to query the store (hence it can just > be locally materialized), but still want to name the processor, they need > to do either "count(Materialized.as(null).withName("processorName"));" or > "count(Named.as("processorName"));" and neither of it is a bit hard to > educate to users, and hence it looks that an overload function with two > parameters are easier to understand. > > 2. As for `NamedOperation`: I've left a comment about it before, i.e. "1) > Regarding the interface / function name, I'd propose we call the interface > `NamedOperation` which would be implemented by Produced / Consumed / > Printed / Joined / Grouped / Suppressed (note I intentionally exclude > Materialized here since its semantics is quite), and have the default class > that implements `NamedOperation` as `Named`, which would be used in our > adding overload functions. The main reason is to have consistency in > naming." And I think I'm on the same page with John with his more detailed > proposal. > > 3. As for `Joined`: I actually would suggest we bite the bullet and remove > it as well, because we are trying to fix some inconsistencies in this KIP > anyways (or is that not agreed upon yet?), my thoughts were that we will > have the following breaking renamings as below: > > 3.a) static Joined#named() -> Joined#as() > 3.b) Joined#name() -> "deleted" > > > I also think that we can start the voting thread asap since we are > achieving to an consensus and the KIP deadline is approaching. The wiki > page itself may still need to be updated though with the API breaking > changes above. > > > Guozhang > > > On Thu, Jan 17, 2019 at 1:43 PM Florian Hussonnois <fhussonn...@gmail.com> > wrote: > >> Sorry, I've sent my previous mail to quickly. Unlike the Consumed, Produced >> and Grouped classes, the Joined class does have getter methods. So I >> propose to keep the name() method only for this class. >> For other classes the name will be accessible through XXXInternal classes. >> >> Le jeu. 17 janv. 2019 à 22:39, John Roesler <j...@confluent.io> a écrit : >> >>> Just to chime in regarding NamedInternal. That was my bad mental model to >>> blame. It is indeed coercion, not casting. Even more relevant, I'm not a >>> fan of the XInternal pattern, but it is the pattern we have. It would be >>> worse to start carving out exceptions. >>> >>> So I agree that we should have: >>> * `NamedOperation` interface, declaring only the `withName(String)` >> setter >>> member >>> * `Named implements NamedOperation` class with a protected `name` field, >>> set by the `withName` setter (and also other config objects would do the >>> same, e.g., `Grouped implements NamedOperation`) >>> * `NamedInternal extends Named` class with a public (but internally >>> targeted) `name()` getter to expose the name to the topology builder. >>> Likewise all the other config classes that implement NamedOperation would >>> expose a `name()` getter for the same purpose. It's not in the public >> API, >>> but we should take care to make sure the getter method has the same name >>> everywhere for minimum confusion. >>> >>> Thanks, everyone! >>> -John >>> >>> On Thu, Jan 17, 2019 at 12:09 PM Bill Bejeck <bbej...@gmail.com> wrote: >>> >>>> I'm getting caught up with the current state of this KIP. >>>> >>>> I agree that the question on what to do with overloads is a difficult >> one >>>> to answer. >>>> >>>> Both John and Matthias have laid out their thoughts thoroughly, and the >>>> points made by both resonate with me. >>>> >>>> I've spent some time thinking about this, and while I have a problem >> with >>>> adding overloaded methods, I can't quite get comfortable with the >> notion >>> of >>>> Materialized naming the processing node. For me, it comes down to the >>> fact >>>> that Materialized is used to configure the state store for an >> individual >>>> processing node and knows nothing of the operation itself. So I'll go >>> with >>>> adding the Named overload to methods taking a Materialized by a narrow >>>> margin. >>>> >>>> As for the name method, I agree with Matthias that it's not consistent >>> with >>>> the approach we've taken so far whether for better or worse, but to >> quote >>>> Matthias, "that ship has sailed." IMHO adding the method for making >>>> testing easier doesn't justify it, as there are ways to get the name >> via >>>> NamedInternal class. >>>> >>>> Just my 2 cents. >>>> >>>> Thanks, >>>> Bill >>>> >>>> On Wed, Jan 16, 2019 at 5:40 PM Matthias J. Sax <matth...@confluent.io >>> >>>> wrote: >>>> >>>>> Thanks for the details John. >>>>> >>>>> While I understand your argument that it is no optimal to use >>>>> `Materialized` to set the processor name, I still slightly prefer >> this >>>>> option, because adding more overloads seems to be even worse to me. >>>>> >>>>> But I would also not block this KIP if the majority of people prefer >> to >>>>> add overloads instead of extending `Materialized`. >>>>> >>>>> >>>>> However, I cannot follow your argument about `NamedOperation#name()` >>>>> getter method. So far, all configuration classes don't have getters >> and >>>>> it seems to be inconsistent to add a single one now. We also don't >> need >>>>> any cast IMHO, as we would use the same construct as we do for all >>> other >>>>> config classed via `NamedInternal` to access the name: >>>>> >>>>>> final String name = new NamedInternal(named).name(); >>>>> >>>>> Maybe, it would have been better to add getters from the beginning on >>>>> (even if I think it was the right decision to not add getters). >>> However, >>>>> this ship have sailed and if we want to add getters to avoid the >>>>> `XxxInternal()` construct, we should do it for all classes -- >> however, >>>>> what would a user gain if we do this? It would just be a lot of >> "noise" >>>>> IMHO. >>>>> >>>>> >>>>> @Florian: I would suggest to start a VOTE if you want to get this >> into >>>>> 2.2 release. The open questions seem to be minor and I think we can >>>>> resolve them in parallel to the vote. >>>>> >>>>> >>>>> >>>>> -Matthias >>>>> >>>>> >>>>> On 1/16/19 12:59 PM, John Roesler wrote: >>>>>> Hi Matthias, >>>>>> >>>>>> One thing that we discussed earlier was to avoid creating ambiguity >>> by >>>>>> conflating config objects that configure an operation (like >> Grouped) >>>> with >>>>>> config objects that configure an aspect of the operation (like >>>>>> Materialized). >>>>>> >>>>>> It is natural for the Grouped config to extend Named, as doing so >>>>> indicates >>>>>> that grouping operations can be named (I.e., the name applies to >> the >>>>>> operation itself, which in turn makes it reasonable to use the >>>>> operation's >>>>>> name as a component in the related processors' and topics' names). >>>>>> >>>>>> But what would it mean for Materialized to extend Named? >> Materialized >>>>> only >>>>>> configures the materialization of an operation's result, not the >>>>> operation >>>>>> itself, so I guess it would mean the name applies to the result of >>> the >>>>>> operation? It doesn't really work. >>>>>> >>>>>> Adding config objects to the DSL was an attempt to avoid overload >>> bloat >>>>> as >>>>>> more aspects of operations need to be configured. >>>>>> However, we made a mistake with Materialized, since (as noted) it >>>> doesn't >>>>>> configure the operation itself, but just one aspect of it. >>>>>> We basically bagged a bunch of parameters into one, without solving >>> the >>>>>> problem structurally, and this is the result: >>>>>> As soon as we need to configure a *different* aspect of the >>> operation, >>>> we >>>>>> again need to add a new overload, and the cycle begins again. >>>>>> >>>>>> The proper solution here is to add an eponymous config object to >> each >>>>>> stateful operation, one which mixes in or composes the Materialized >>>>> aspect >>>>>> config and the Named aspect config. But this is a large API change, >>> and >>>>> we >>>>>> decided on the middle ground of just adding Named as an optional >>>>> parameter >>>>>> via new overloads for now. >>>>>> >>>>>> A similar compromise was to go ahead and add a Named overload >>> directly >>>> to >>>>>> all the operators that currently have no config object. >>>>>> Again, the proper thing would be to add a new config class for each >>>>>> individual operation, but it seemed like a drastic change. >>>>>> We basically said that right now, we don't think we'll ever need to >>>>>> configure another aspect of those operators than the name, and >> we're >>>>>> acknowledging that if we do, we'll have to created a small mess to >>>> clean >>>>> up. >>>>>> It's really just a generalization of the same problem with >>> Materialized >>>>>> operations. >>>>>> >>>>>> To answer your question about the Named interface: >>>>>> The primary reason is that Named is an aspect that is meant to be >>> mixed >>>>> in >>>>>> with other config objects. >>>>>> For example, Grouped can extend Named. >>>>>> If we followed the pattern you've referenced, we would have a >> public >>>>>> interface Named with only the setter and a private class >>> NamedInternal >>>>> with >>>>>> the setter and getter. >>>>>> But would Grouped be a subclass of NamedInternal? >>>>>> Then, we could only have one kind of aspect mixin, since Java >> doesn't >>>>> have >>>>>> multiple class inheritance, or we'd have to decide if the next >> thing >>>>> should >>>>>> be a superclass of Named or a subclass of Named and a superclass of >>>>> Grouped. >>>>>> Plus, in the implementation, instead of just casting Grouped to >>>>>> GroupedInternal (which is already unclean design), we'd also be >>> casting >>>>>> Grouped to NamedInternal, which is super confusing. >>>>>> >>>>>> It's far cleaner all around just to use the type system "the right >>>> way", >>>>>> which is what we've proposed. >>>>>> Any config class can mix in the Named aspect, and it inherits a >>>> contract >>>>> to >>>>>> supply both the setter and the getter. >>>>>> Our implementation can actually avoid any casting in this usage, >>> since >>>> we >>>>>> can just call grouped.name() to get the name, instead of something >>>> like >>>>>> ((NamedInternal) grouped).name(). >>>>>> >>>>>> Plus, what harm does it do to let people get back the configuration >>>>>> property that they *just set* on the config object? >>>>>> It doesn't break encapsulation. >>>>>> It would certainly make writing tests a lot easier for everyone. >>>>>> >>>>>> All around, I would advocate for moving toward this design for all >>> the >>>>>> config interfaces, as I've previously demonstrated how we've made >> an >>>>>> intractable mess out of the window config hierarchy by trying to be >>>>> clever >>>>>> and hiding the getters. >>>>>> >>>>>> I hope this helps, >>>>>> -John >>>>>> >>>>>> >>>>>> On Wed, Jan 16, 2019 at 12:59 AM Matthias J. Sax < >>>> matth...@confluent.io> >>>>>> wrote: >>>>>> >>>>>>> While I understand that it should be possible to specify store >> name >>>> and >>>>>>> processor name independent from each other, it's still unclear to >>> me, >>>>>>> why we cannot use the `Materialized` parameter to specify the >>>> processor >>>>>>> name: >>>>>>> >>>>>>>> // only set the node name >>>>>>>> #count(Named.as("processorName")); >>>>>>>> >>>>>>>> // only set the store name >>>>>>>> #count(Materialized.as("storeName")); >>>>>>>> >>>>>>>> // set both >>>>>>>> #count(Materialized.as("storeName").withName("processorName")); >>>>>>> >>>>>>> This this case, it might be good to rename `withName` to >>>>>>> `withProcessorName` to avoid confusion with the store name. >>>>>>> >>>>>>> However, why do we need this: >>>>>>> >>>>>>>> #count(Materialized.as("storeName"), Named.as("processorName")); >>>>>>> >>>>>>> I would prefer to not add this overload. >>>>>>> >>>>>>> >>>>>>> >>>>>>> Strictly, we could also avoid `#count(Named)`, and set the >> processor >>>>>>> name only via: >>>>>>> >>>>>>>> #count(Materialized.as(null).withName("processorName")); >>>>>>> >>>>>>> I admit, it's a little clumsy, but would save us one more >> overload. >>>>>>> >>>>>>> >>>>>>> >>>>>>> One more comment that I forgot last time: why do we add the getter >>>>>>> `Named#name()`? All other configuration classes only define >> setters >>>> and >>>>>>> we add getters only in the internal implementation. >>>>>>> >>>>>>> >>>>>>> -Matthias >>>>>>> >>>>>>> On 1/13/19 4:22 AM, Florian Hussonnois wrote: >>>>>>>> Hi Matthias, >>>>>>>> >>>>>>>> The reason for overloading the methods with Materialized >> parameter >>> is >>>>>>>> regarding the semantic of this class. >>>>>>>> The Materialized class allow to name a queryable store. if a name >>> is >>>>> set >>>>>>>> then it will be used both to name the state-store and the >>>>>>> changelog-topic. >>>>>>>> If no name is given, then the provided Named will be used. >>>>>>>> This allow to name the operation without having a queriable >> store. >>>>>>>> >>>>>>>> So if my analysis is correct, we will end up with : >>>>>>>> >>>>>>>> Generated | Named | Joined / >>>>>>> Grouped >>>>>>>> | Materialized >>>>>>>> >>>>>>> >>>>> >>>> >>> >> ------------------------------------------------------------------------------------------------- >>>>>>>> Node | X | X | >>> X >>>>>>>> | >>>>>>>> >>>>>>> >>>>> >>>> >>> >> ------------------------------------------------------------------------------------------------- >>>>>>>> Repartition Topic | X | | X >>>>>>>> | >>>>>>>> >>>>>>> >>>>> >>>> >>> >> ------------------------------------------------------------------------------------------------- >>>>>>>> Queryable Store | | | >>>>>>>> | X >>>>>>>> >>>>>>> >>>>> >>>> >>> >> ------------------------------------------------------------------------------------------------- >>>>>>>> State store | X | X | >> X >>>>>>>> | X >>>>>>>> >>>>>>> >>>>> >>>> >>> >> ------------------------------------------------------------------------------------------------- >>>>>>>> Changelog Topic | X | X | X >>>>>>>> | X >>>>>>>> >>>>>>> >>>>> >>>> >>> >> ------------------------------------------------------------------------------------------------- >>>>>>>> >>>>>>>> Le dim. 13 janv. 2019 à 03:23, Matthias J. Sax < >>>> matth...@confluent.io> >>>>> a >>>>>>>> écrit : >>>>>>>> >>>>>>>>> Just catching up on this KIP again. >>>>>>>>> >>>>>>>>> One nit. The KIP says: >>>>>>>>> >>>>>>>>>> In addition, the generated names have a few disadvantages to >>>>> guarantee >>>>>>>>> topology compatibilities. In fact, adding a new operator, using >> a >>>>>>>>> third-library doing some optimization to remove some operators >> or >>>>>>> upgrading >>>>>>>>> to a new KafkaStreams version with internal API changes may >>> changed >>>>>>> suffix >>>>>>>>> indexing for a large amount of the processor names. This will in >>>> turn >>>>>>>>> change the internal state store names, as well as internal topic >>>> names >>>>>>> as >>>>>>>>> well. >>>>>>>>>> >>>>>>>>> >>>>>>>>> This is not true any longer (I guess it was true, when the KIP >> was >>>>>>>>> initially proposed), because all stores/internal-topics can be >>> named >>>>>>>>> since 2.1 release. I would suggest to remove the paragraph. >>>>>>>>> >>>>>>>>> Overall, I like the Named/NamedOperation design. >>>>>>>>> >>>>>>>>> What is unclear to me thought is, why we need new overloads for >>>>> methods >>>>>>>>> that accept `Materialized`. To be more precise, I think it make >>>> sense >>>>> to >>>>>>>>> add an overload that only takes `Named`, but not one that takes >>> both >>>>>>>>> `Named` and `Materialized`. For example: >>>>>>>>> >>>>>>>>> KGroupedStream#count() // exists >>>>>>>>> KGroupedStream#count(Materialized) // exits >>>>>>>>> KGroupedStream#count(Named) // added (makes sense to me) >>>>>>>>> KGroupedStream#count(Named, Materialized) // added -- why? >>>>>>>>> >>>>>>>>> I would prefer to use `Materialized` to name the processor for >>> this >>>>>>>>> case, too. Can you elaborate on the motivation? >>>>>>>>> >>>>>>>>> >>>>>>>>> -Matthias >>>>>>>>> >>>>>>>>> On 1/11/19 3:39 PM, Florian Hussonnois wrote: >>>>>>>>>> Hi Guozhang, >>>>>>>>>> >>>>>>>>>> I have updated the PR as well as the KIP. I should add more >> unit >>>>> tests >>>>>>> to >>>>>>>>>> covers all new methods. >>>>>>>>>> >>>>>>>>>> However, I still have one test in failure. The reason is that >>> using >>>>>>>>>> Joined.name() in both potential repartition topic and processor >>>> nodes >>>>>>>>> leads >>>>>>>>>> to topology-incompatible. >>>>>>>>>> How should we deal with that ? >>>>>>>>>> >>>>>>>>>> Thanks, >>>>>>>>>> >>>>>>>>>> Le jeu. 10 janv. 2019 à 01:21, Guozhang Wang < >> wangg...@gmail.com >>>> >>>> a >>>>>>>>> écrit : >>>>>>>>>> >>>>>>>>>>> Hello Florian, >>>>>>>>>>> >>>>>>>>>>> Just checking if have read about my previous email and if you >>> feel >>>>>>> happy >>>>>>>>>>> about it. We have the 2.2 KIP freeze deadline at 24th this >>> month, >>>>>>> while >>>>>>>>> the >>>>>>>>>>> PR itself is getting quite close. So it'll be great if we can >>> get >>>>> the >>>>>>>>>>> agreement on it and get it into 2.2.0 release. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Guozhang >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Mon, Dec 17, 2018 at 2:39 PM Guozhang Wang < >>> wangg...@gmail.com >>>>> >>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Florian / John, >>>>>>>>>>>> >>>>>>>>>>>> Just wanted to throw a couple minor thoughts on the current >>>>> proposal: >>>>>>>>>>>> >>>>>>>>>>>> 1) Regarding the interface / function name, I'd propose we >> call >>>> the >>>>>>>>>>>> interface `NamedOperation` which would be implemented by >>>> Produced / >>>>>>>>>>>> Consumed / Printed / Joined / Grouped / Suppressed (note I >>>>>>>>> intentionally >>>>>>>>>>>> exclude Materialized here since its semantics is quite), and >>> have >>>>> the >>>>>>>>>>>> default class that implements `NamedOperation` as `Named`, >>> which >>>>>>> would >>>>>>>>> be >>>>>>>>>>>> used in our adding overload functions. The main reason is to >>> have >>>>>>>>>>>> consistency in naming. >>>>>>>>>>>> >>>>>>>>>>>> 2) As a minor tweak, I think it's better to use Joined.name() >>> in >>>>> both >>>>>>>>> its >>>>>>>>>>>> possibly generate repartition topic, as well as the map >>> processor >>>>>>> used >>>>>>>>> for >>>>>>>>>>>> group-by (currently this name is only used for the >> repartition >>>>>>> topic). >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Florian: if you think this proposal makes sense, please feel >>> free >>>>> to >>>>>>> go >>>>>>>>>>>> ahead and update the PR; after we made a first pass on it and >>>> feels >>>>>>>>>>>> confident about it, we can go ahead with the VOTING process. >>>> About >>>>>>> the >>>>>>>>>>>> implementation of 2) above, this may be out of your >>>> implementation >>>>>>>>> scope, >>>>>>>>>>>> so feel free to leave it out side your PR while Bill who >>>> originally >>>>>>>>> worked >>>>>>>>>>>> on the Grouped KIP can make a follow-up PR for it. >>>>>>>>>>>> >>>>>>>>>>>> Guozhang >>>>>>>>>>>> >>>>>>>>>>>> On Fri, Dec 14, 2018 at 9:43 PM Guozhang Wang < >>>> wangg...@gmail.com> >>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hello Florian, >>>>>>>>>>>>> >>>>>>>>>>>>> Really appreciate you for your patience. >>>>>>>>>>>>> >>>>>>>>>>>>> I know that we've discussed about the approach to adding >>>>> overloaded >>>>>>>>>>>>> functions and rejected it early on. But looking deeper into >>> the >>>>>>>>> current PR >>>>>>>>>>>>> I realized that this approach has a danger of great API >>>> confusions >>>>>>> to >>>>>>>>> users >>>>>>>>>>>>> (I tried to explain my thoughts in the PR, but it was not >> very >>>>>>> clear) >>>>>>>>> --- >>>>>>>>>>>>> the basic idea is that, today we already have a few existing >>>>> control >>>>>>>>>>>>> classes including Grouped, Joined, Suppressed that allow >> users >>>> to >>>>>>>>> specify >>>>>>>>>>>>> serdes etc, while also a "name" which can then be used to >>> define >>>>> the >>>>>>>>>>>>> processor name / internal topic names in the topology (the >>>> static >>>>>>>>> function >>>>>>>>>>>>> names are not consistent, which I think we should fix as >>> well). >>>>> And >>>>>>>>> Named >>>>>>>>>>>>> interface, by extending the lambda function interfaces like >>>>>>>>> ValueJoiner / >>>>>>>>>>>>> Predicate etc opens the door for another way to specify the >>>> names >>>>>>>>> again. >>>>>>>>>>>>> >>>>>>>>>>>>> So in order to achieve consistency, we are left with >> generally >>>> two >>>>>>>>>>>>> options: >>>>>>>>>>>>> >>>>>>>>>>>>> 1) only allow users to specify names via the lambda >> interfaces >>>>> that >>>>>>>>>>>>> extends Named interface. This means we'd better remove the >>>> naming >>>>>>>>> mechanism >>>>>>>>>>>>> from the existing control objects to keep consistency. >>>>>>>>>>>>> >>>>>>>>>>>>> 2) only allow users to specify names via control classes, >> and >>> we >>>>>>>>>>>>> introduce a new class (Named) for those which do not have >> one >>>> yet >>>>>>> --- >>>>>>>>> this >>>>>>>>>>>>> leads to the overloaded functions. >>>>>>>>>>>>> >>>>>>>>>>>>> I did a quick count on the num.of overloaded functions, and >>>>> summing >>>>>>>>> from >>>>>>>>>>>>> KTable (8) / KStream (15) / KGroupedStream (6) / >> KGroupedTable >>>>> (6) / >>>>>>>>>>>>> TimeWindowedKStream (6) / SessionWindowedKStream (6) we got >>>> about >>>>> 47 >>>>>>>>>>>>> overloaded functions (our guess was pretty close!) -- note >>> this >>>> is >>>>>>>>> based on >>>>>>>>>>>>> John's proposal that we can let existing Grouped / Joined to >>>>> extend >>>>>>>>> Named >>>>>>>>>>>>> and hence we only need overloaded functions with a default >>>>>>>>> NamedOperation >>>>>>>>>>>>> for those operators that do not have a control classes >>> already. >>>>>>>>>>>>> >>>>>>>>>>>>> Thinking about this approach I feel it is not too bad >> compared >>>>> with >>>>>>>>>>>>> either 1) above, which would require us to deprecate lot of >>>> public >>>>>>>>>>>>> functions around name(), or having a mixed mechanism for >>> naming, >>>>>>> which >>>>>>>>>>>>> could lead to very confusing behavior to users. >> Additionally, >>>> for >>>>>>> most >>>>>>>>>>>>> users who would only want to specify the names for those >>>> stateful >>>>>>>>>>>>> operations which have internal topics / state stores and >> hence >>>> are >>>>>>>>> more >>>>>>>>>>>>> keen to upgrade compatibility, those added overloads would >> be >>>>>>>>> not-often >>>>>>>>>>>>> used functions for them anyways. And by letting existing >>> control >>>>>>>>> classes to >>>>>>>>>>>>> extend Named, we can have a unified method name for static >>>>>>>>> constructor as >>>>>>>>>>>>> well. >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Guozhang >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Fri, Dec 14, 2018 at 10:24 AM John Roesler < >>>> j...@confluent.io> >>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Florian, >>>>>>>>>>>>>> >>>>>>>>>>>>>> Sorry about the run-around of rejecting the original >>> proposal, >>>>>>>>>>>>>> only to return to it later on. Hopefully, it's more >>> encouraging >>>>>>>>>>>>>> than frustrating that we're coming around to your initial >> way >>>> of >>>>>>>>>>>>>> thinking. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Thanks! >>>>>>>>>>>>>> -John >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Thu, Dec 13, 2018 at 4:28 PM Florian Hussonnois < >>>>>>>>>>>>>> fhussonn...@gmail.com> >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi all, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Thanks again. I agree with your propositions. >>>>>>>>>>>>>>> Also IMHO, overloading all methods (filter, map) to >> accept a >>>> new >>>>>>>>>>>>>> control >>>>>>>>>>>>>>> object seems to provide a more natural development >>> experience >>>>> for >>>>>>>>>>>>>> users. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Actually, this was the first proposition for this KIP, but >>> we >>>>> have >>>>>>>>>>>>>> rejected >>>>>>>>>>>>>>> it because this solution led to adding a lot of new >> methods. >>>>>>>>>>>>>>> As you mentioned it, the API has evolve since the creation >>> of >>>>> this >>>>>>>>>>>>>> KIP - >>>>>>>>>>>>>>> some existing control objects already allow to customize >>>>> internal >>>>>>>>>>>>>> names. We >>>>>>>>>>>>>>> should so keep on that strategy. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> If everyone is OK with that, I will update the KIP and the >>> PR >>>>>>>>>>>>>> accordingly; >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Thanks. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Le jeu. 13 déc. 2018 à 18:08, John Roesler < >>> j...@confluent.io >>>>> >>>>> a >>>>>>>>>>>>>> écrit : >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi again, all, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Matthias, I agree with you. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Florian, thanks for your response. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I think your proposal is the best way to address the ask >>> for >>>>>>> hiding >>>>>>>>>>>>>> the >>>>>>>>>>>>>>>> name() getter. But I'd like to question that ask and >>> instead >>>>>>>>>>>>>> propose that >>>>>>>>>>>>>>>> we just make the name() getter part of the public API. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> The desire to "hide" the getters causes a lot of >> complexity >>>> in >>>>>>> our >>>>>>>>>>>>>> code >>>>>>>>>>>>>>>> base, and it will become completely impractical with the >>>> mixin >>>>>>>>>>>>>> strategy >>>>>>>>>>>>>>> of >>>>>>>>>>>>>>>> Named. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> If we were to switch strategies back to mixing Named in >> to >>>> the >>>>>>>>>>>>>> control >>>>>>>>>>>>>>>> objects rather than the functions, then the path forward >>>>> becomes >>>>>>>>>>>>>> quite >>>>>>>>>>>>>>>> clear. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On the other hand, it seems harmless for anyone who wants >>> to >>>> be >>>>>>>>>>>>>> able to >>>>>>>>>>>>>>>> query the name from a control object after setting it, so >>> my >>>>> vote >>>>>>>>>>>>>> would >>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>> simply to keep the Named interface as: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> public interface Named<T extends Named<T>> { >>>>>>>>>>>>>>>> String name(); >>>>>>>>>>>>>>>> T withName(String name); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Under this proposal, we only mix Named in to the control >>>>> objects, >>>>>>>>>>>>>> which >>>>>>>>>>>>>>>> means we have no need of default implementations anymore >>>>> (because >>>>>>>>>>>>>> we can >>>>>>>>>>>>>>>> update all the control objects concurrently with adding >>> this >>>>>>>>>>>>>> interface to >>>>>>>>>>>>>>>> them). >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> This does hinge on switching over to a >> control-object-only >>>>>>>>> strategy, >>>>>>>>>>>>>>> which >>>>>>>>>>>>>>>> introduces the need to add about 50 new control object >>>> classes, >>>>>>>>>>>>>> which >>>>>>>>>>>>>>> would >>>>>>>>>>>>>>>> only serve to implement Named. As a middle ground, maybe >> we >>>>> could >>>>>>>>>>>>>> just >>>>>>>>>>>>>>> add >>>>>>>>>>>>>>>> one generic control object class, like: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> public class NamedOperation implements >>> Named<NamedOperation> >>>> { >>>>>>>>>>>>>>>> private final String name; >>>>>>>>>>>>>>>> private NamedOperation(final String name) { this.name >> = >>>>> name; >>>>>>> } >>>>>>>>>>>>>>>> public static NamedOperation name(final String name) { >>>>>>>>>>>>>>>> return new NamedOperation(name); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> public String name() { return name; } >>>>>>>>>>>>>>>> public NamedOperation withName(final String name) { >>>>>>>>>>>>>>>> return new NamedOperation(name); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> And then, we'd add overloads for all the methods that >> don't >>>>> have >>>>>>>>>>>>>> control >>>>>>>>>>>>>>>> objects already (for example, filter() ): >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> // existing >>>>>>>>>>>>>>>> KStream<K, V> filter(Predicate<? super K, ? super V> >>>>> predicate); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> // new >>>>>>>>>>>>>>>> KStream<K, V> filter(Predicate<? super K, ? super V> >>>> predicate, >>>>>>>>>>>>>>>> NamedOperation named); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Additionally, in regard to Matthias's point about >> existing >>>>>>> control >>>>>>>>>>>>>>> objects >>>>>>>>>>>>>>>> with naming semantics, they would extend Named (but not >>>>>>>>>>>>>> NamedOperation) >>>>>>>>>>>>>>> for >>>>>>>>>>>>>>>> uniformity. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> You provided a good approach to hide the getter with your >>>>>>>>>>>>>> SettableName >>>>>>>>>>>>>>>> class; I think what you proposed is the only way we could >>>> hide >>>>>>> the >>>>>>>>>>>>>> name. >>>>>>>>>>>>>>>> In the end, though, it's a lot of complexity added >> (control >>>>>>> object >>>>>>>>>>>>>> class >>>>>>>>>>>>>>>> hierarchy, inheritance, mutable state, internal casting) >>> for >>>>>>>>>>>>>> something of >>>>>>>>>>>>>>>> dubious value: to be able to hide the name from someone >>>> *after >>>>>>> they >>>>>>>>>>>>>>>> themselves have set it*. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Although it'll be a pain, perhaps Matthias's suggestion >> to >>>>>>>>>>>>>> enumerate all >>>>>>>>>>>>>>>> the API methods is the best way to be sure we all agree >> on >>>>> what's >>>>>>>>>>>>>> going >>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>> happen. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Thanks again for wrangling with this issue, >>>>>>>>>>>>>>>> -John >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Thu, Dec 13, 2018 at 9:03 AM Matthias J. Sax < >>>>>>>>>>>>>> matth...@confluent.io> >>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Just catching up on this discussion. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> My overall personal take is, that I am not a big fan of >>> the >>>>>>>>>>>>>> interface >>>>>>>>>>>>>>>>> `Named` that is used as a factory. I would rather prefer >>> to >>>>> add >>>>>>> a >>>>>>>>>>>>>>>>> control object parameter to all methods that don't have >>> one >>>>> yet. >>>>>>>>>>>>>> This >>>>>>>>>>>>>>>>> KIP was started a while ago, and we added new naming >>>>>>> capabilities >>>>>>>>>>>>>> in >>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>> meantime. Guozhang's example in the PR comment about >>> naming >>>> in >>>>>>>>>>>>>>>>> stream-stream join shows, that we might end up in a >>>> confusion >>>>>>>>>>>>>> situation >>>>>>>>>>>>>>>>> for users if we use `Named`. Also, in 2.1, user can >>> already >>>>> name >>>>>>>>>>>>>> as >>>>>>>>>>>>>>>>> repartition-/changelog-topics and stores. Thus, KIP-307 >>>> boils >>>>>>>>>>>>>> down to >>>>>>>>>>>>>>>>> provide non-functional naming? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hence, for all methods that allow to specify names >>> already, >>>> I >>>>>>>>>>>>>> don't see >>>>>>>>>>>>>>>>> any reason to change them, but use the existing API to >>> also >>>>> name >>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>> processor(s) instead of allowing uses to specify a new >>> name. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> About the inconsistency in method naming. I agree, that >>> `as` >>>>> is >>>>>>>>>>>>>> very >>>>>>>>>>>>>>>>> generic and maybe not the best choice. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I think it might be helpful, to have a table overview in >>> the >>>>>>> KIP, >>>>>>>>>>>>>> that >>>>>>>>>>>>>>>>> list all existing static/non-static methods that allow >> to >>>>>>> specify >>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>> name, plus a columns with the new suggested naming for >>> those >>>>>>>>>>>>>> methods? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Thoughts? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -Matthias >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On 12/12/18 12:45 AM, Florian Hussonnois wrote: >>>>>>>>>>>>>>>>>> Thank you very much for your feedbacks. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Currently, there is still lot of discussions regarding >>> the >>>>>>> Named >>>>>>>>>>>>>>>>> interface. >>>>>>>>>>>>>>>>>> On the one hand we should provided consistency over the >>>>> stream >>>>>>>>>>>>>> API >>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>> on >>>>>>>>>>>>>>>>>> the other hand we should not break the semantic as John >>>> point >>>>>>>>>>>>>> it up. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Guozhang, I'm sorry, but I'm little bit confused, >> maybe I >>>>>>> missed >>>>>>>>>>>>>>>>> something. >>>>>>>>>>>>>>>>>> In your comment you have suggested that : >>>>>>>>>>>>>>>>>> * Produced/Consumed/Suppressed should extends Named >>>>>>>>>>>>>>>>>> * Named should have a private-package method to get the >>>>>>>>>>>>>> specified >>>>>>>>>>>>>>>>> processor >>>>>>>>>>>>>>>>>> name internally (processorName()) >>>>>>>>>>>>>>>>>> * Finally we should end up with something like : Named >>> -> >>>>> XXX >>>>>>>>>>>>>> -> >>>>>>>>>>>>>>>>>> XXXInternal or Named -> Produced -> ProducedInternal >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> The objective behind that is to : >>>>>>>>>>>>>>>>>> * consolidate the internal method processorName() >>>>>>>>>>>>>>>>>> * consolidate the method withName that exists now >>> existing >>>>> into >>>>>>>>>>>>>>>> Produced, >>>>>>>>>>>>>>>>>> Consumed and Suppressed. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> But, Named is an interface so we can't define a >>>>> private-package >>>>>>>>>>>>>>> method >>>>>>>>>>>>>>>> on >>>>>>>>>>>>>>>>>> it. Also, for example Produced and ProducedInternal are >>> not >>>>> in >>>>>>>>>>>>>> the >>>>>>>>>>>>>>> same >>>>>>>>>>>>>>>>>> package so having a private-package method doesn't >> really >>>>> help. >>>>>>>>>>>>>>>>>> In addition, if we add the withName method into Named >>>>> interface >>>>>>>>>>>>>> this >>>>>>>>>>>>>>>> can >>>>>>>>>>>>>>>>>> become confusing for developers because action >> interfaces >>>>>>>>>>>>>>> (ValueMapper, >>>>>>>>>>>>>>>>>> Reducer, etc) extend it. >>>>>>>>>>>>>>>>>> The interface would look like : >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> public interface Named<T extends Named<T>> { >>>>>>>>>>>>>>>>>> default String name() { >>>>>>>>>>>>>>>>>> return null; >>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>> default Named<T> withName(final String name) { >>>>>>>>>>>>>>>>>> return null; >>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>> ... >>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> So maybe instead of adding another method to Named we >>> could >>>>>>>>>>>>>> create a >>>>>>>>>>>>>>>> new >>>>>>>>>>>>>>>>>> package-private class that could be extended by >>>>>>>>>>>>>>>>>> Produced/Consumed/Joined/Suppressed. For exemple, >>>>>>>>>>>>>>>>>> class SettableName<T extends SettableName<T>> >> implements >>>>> Named >>>>>>> { >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> protected String processorName; >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> SettableName(final SettableName settable) { >>>>>>>>>>>>>>>>>> this(Objects.requireNonNull(settable, "settable >>>> can't >>>>>>> be >>>>>>>>>>>>>>>>>> null").name()); >>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> SettableName(final String processorName) { >>>>>>>>>>>>>>>>>> this.processorName = processorName; >>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> @Override >>>>>>>>>>>>>>>>>> public String name() { >>>>>>>>>>>>>>>>>> return processorName; >>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>> public T withName(final String processorName) { >>>>>>>>>>>>>>>>>> this.processorName = processorName; >>>>>>>>>>>>>>>>>> return (T)this; >>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> In that way, we will get : public class Produced >>> implements >>>>>>>>>>>>>>>>>> SettableName<Produced> { ... >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> WDYT? >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Le mar. 11 déc. 2018 à 02:46, Guozhang Wang < >>>>>>> wangg...@gmail.com> >>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>> écrit : >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> I had one meta comment on the PR: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>> https://github.com/apache/kafka/pull/5909#discussion_r240447153 >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Mon, Dec 10, 2018 at 5:22 PM John Roesler < >>>>>>>>>>>>>> j...@confluent.io> >>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Florian, >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> I hope it's ok if I ask a few questions at this late >>>>> stage... >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Comment 1 ====== >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> It seems like the proposal is to add a new "Named" >>>>> interface >>>>>>>>>>>>>> that >>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>>>>>> intended to be mixed in with the existing API objects >>> at >>>>>>>>>>>>>> various >>>>>>>>>>>>>>>>> points. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Just to preface some of my comments, it looks like >> your >>>> KIP >>>>>>>>>>>>>> was >>>>>>>>>>>>>>>> created >>>>>>>>>>>>>>>>>>>> quite a while ago, so the API may have changed >> somewhat >>>>> since >>>>>>>>>>>>>> you >>>>>>>>>>>>>>>>>>> started. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> As I see the API, there are a few different kinds of >>> DSL >>>>>>>>>>>>>> method >>>>>>>>>>>>>>>>>>> arguments: >>>>>>>>>>>>>>>>>>>> * functions: things like Initializer, Aggregator, >>>>>>> ValueJoiner, >>>>>>>>>>>>>>>>>>>> ForEachAction... All of these are essentially >>>>>>> Streams-flavored >>>>>>>>>>>>>>>> Function >>>>>>>>>>>>>>>>>>>> interfaces with different arities, type bounds, and >>>>>>> semantics. >>>>>>>>>>>>>>>>>>>> * config objects: things like Produced, Consumed, >>> Joined, >>>>>>>>>>>>>>> Grouped... >>>>>>>>>>>>>>>>>>> These >>>>>>>>>>>>>>>>>>>> are containers for configurations, where the target >> of >>>> the >>>>>>>>>>>>>>>>> configuration >>>>>>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>>>>>> the operation itself >>>>>>>>>>>>>>>>>>>> * raw configurations: things like a raw topic-name >>> string >>>>> and >>>>>>>>>>>>>>>>>>> Materialized: >>>>>>>>>>>>>>>>>>>> These are configurations for operations that have no >>>> config >>>>>>>>>>>>>> object, >>>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>> for >>>>>>>>>>>>>>>>>>>> various reasons, we didn't make one. The >> distinguishing >>>>>>>>>>>>>> feature is >>>>>>>>>>>>>>>> that >>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>> target of the configuration is not the operation >>> itself, >>>>> but >>>>>>>>>>>>>> some >>>>>>>>>>>>>>>>> aspect >>>>>>>>>>>>>>>>>>> of >>>>>>>>>>>>>>>>>>>> it. For example, in Materialized, we are not setting >>> the >>>>>>>>>>>>>> caching >>>>>>>>>>>>>>>>> behavior >>>>>>>>>>>>>>>>>>>> of, for example, an aggregation; we're setting the >>>> caching >>>>>>>>>>>>>> behavior >>>>>>>>>>>>>>>> of >>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>>> materialized state store attached to the aggregation. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> It seems like choosing to mix the Named interface in >>> with >>>>> the >>>>>>>>>>>>>>>> functions >>>>>>>>>>>>>>>>>>> has >>>>>>>>>>>>>>>>>>>> a couple of unfortunate side-effects: >>>>>>>>>>>>>>>>>>>> * Aggregator is not the only function passed to any >> of >>>> the >>>>>>>>>>>>>> relevant >>>>>>>>>>>>>>>>>>>> aggregate methods, so it seems a little arbitrary to >>> pick >>>>>>> that >>>>>>>>>>>>>>>> function >>>>>>>>>>>>>>>>>>>> over Initializer or Merger. >>>>>>>>>>>>>>>>>>>> * As you noted, branch() takes an array of Predicate, >>> so >>>> we >>>>>>>>>>>>>> just >>>>>>>>>>>>>>>> ignore >>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>> provided name(s), even though Predicate names are >> used >>>>>>>>>>>>>> elsewhere. >>>>>>>>>>>>>>>>>>>> * Not all things that we want to name have function >>>>>>> arguments, >>>>>>>>>>>>>>>> notably >>>>>>>>>>>>>>>>>>>> source and sink, so we'd switch paradigms and use the >>>>> config >>>>>>>>>>>>>> object >>>>>>>>>>>>>>>>>>>> instead. >>>>>>>>>>>>>>>>>>>> * Adding an extra method to the function interfaces >>> means >>>>>>> that >>>>>>>>>>>>>>> those >>>>>>>>>>>>>>>>> are >>>>>>>>>>>>>>>>>>> no >>>>>>>>>>>>>>>>>>>> longer SAM interfaces. You proposed to add a default >>>>>>>>>>>>>>> implementation, >>>>>>>>>>>>>>>> so >>>>>>>>>>>>>>>>>>> we >>>>>>>>>>>>>>>>>>>> could still pass a lambda if we don't want to set the >>>> name, >>>>>>>>>>>>>> but if >>>>>>>>>>>>>>> we >>>>>>>>>>>>>>>>>>> *do* >>>>>>>>>>>>>>>>>>>> want to set the name, we can no longer use lambdas. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> I think the obvious other choice would be to mix >> Named >>> in >>>>>>>>>>>>>> with the >>>>>>>>>>>>>>>>> config >>>>>>>>>>>>>>>>>>>> objects instead, but this has one main downside of >> its >>>>> own... >>>>>>>>>>>>>>>>>>>> * not every operator we wish to name has a config >>>> object. I >>>>>>>>>>>>>> don't >>>>>>>>>>>>>>>> know >>>>>>>>>>>>>>>>> if >>>>>>>>>>>>>>>>>>>> everyone involved is comfortable with adding a config >>>>> object >>>>>>>>>>>>>> to >>>>>>>>>>>>>>> every >>>>>>>>>>>>>>>>>>>> operator that's missing one. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Personally, I favor moving toward a more consistent >>> state >>>>>>>>>>>>>> that's >>>>>>>>>>>>>>>>> forward >>>>>>>>>>>>>>>>>>>> compatible with any further changes we wish to make. >> I >>>>>>>>>>>>>> *think* that >>>>>>>>>>>>>>>>>>> giving >>>>>>>>>>>>>>>>>>>> every operator two forms (one with no config and one >>>> with a >>>>>>>>>>>>>> config >>>>>>>>>>>>>>>>>>> object) >>>>>>>>>>>>>>>>>>>> would be such an API. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Comment 2 ========= >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Finally, just a minor comment: the static method in >>> Named >>>>>>>>>>>>>> wouldn't >>>>>>>>>>>>>>>> work >>>>>>>>>>>>>>>>>>>> properly as defined. Assuming that we mix Named in >> with >>>>>>>>>>>>>> Produced, >>>>>>>>>>>>>>> for >>>>>>>>>>>>>>>>>>>> example, we'd need to be able to use it like: >>>>>>>>>>>>>>>>>>>>> kStream.to("out", Produced.with("myOut")) >>>>>>>>>>>>>>>>>>>> This doesn't work because with() returns a Named, but >>> we >>>>> need >>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>> Produced. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> We can pull off a builder method in the interface, >> but >>>> not >>>>> a >>>>>>>>>>>>>> static >>>>>>>>>>>>>>>>>>> method. >>>>>>>>>>>>>>>>>>>> To define a builder method in the interface that >>> returns >>>> an >>>>>>>>>>>>>>> instance >>>>>>>>>>>>>>>> of >>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>> concrete subtype, you have to use the "curiously >>>> recurring >>>>>>>>>>>>>> generic" >>>>>>>>>>>>>>>>>>>> pattern. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> It would look like: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> public interface Named<N extends Named<N>> { >>>>>>>>>>>>>>>>>>>> String name(); >>>>>>>>>>>>>>>>>>>> N withName(String name); >>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> You can see where the name of the pattern comes from >> ;) >>>>>>>>>>>>>>>>>>>> An implementation would then look like: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> public class Produced implements Named<Produced> { >>>>>>>>>>>>>>>>>>>> String name() { return name; } >>>>>>>>>>>>>>>>>>>> Produced withName(final String name) { this.name = >>>> name; >>>>>>>>>>>>>> return >>>>>>>>>>>>>>>>> this; >>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Note that the generic parameter gets filled in >> properly >>>> in >>>>>>> the >>>>>>>>>>>>>>>>>>> implementing >>>>>>>>>>>>>>>>>>>> class, so that you get the right return type out. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> It doesn't work at all with a static factory method >> at >>>> the >>>>>>>>>>>>>>> interface >>>>>>>>>>>>>>>>>>> level, >>>>>>>>>>>>>>>>>>>> so it would be up to Produced to define a static >>> factory >>>> if >>>>>>> it >>>>>>>>>>>>>>> wants >>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>> present one. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> ====== >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Those are my two feedbacks! >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> I hope you find this helpful, rather than >> frustrating. >>>> I'm >>>>>>>>>>>>>> sorry I >>>>>>>>>>>>>>>>> didn't >>>>>>>>>>>>>>>>>>>> get a chance to comment sooner. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Thanks for the KIP, I think it will be much nicer to >> be >>>>> able >>>>>>>>>>>>>> to >>>>>>>>>>>>>>> name >>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>> processor nodes. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> -John >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Tue, Nov 27, 2018 at 6:34 PM Guozhang Wang < >>>>>>>>>>>>>> wangg...@gmail.com> >>>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi Florian, >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> I've made a pass over the PR. There are some >> comments >>>> that >>>>>>>>>>>>>> are >>>>>>>>>>>>>>>> related >>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>> the function names which may be affecting the KIP >> wiki >>>>> page, >>>>>>>>>>>>>> but >>>>>>>>>>>>>>>>>>> overall >>>>>>>>>>>>>>>>>>>> I >>>>>>>>>>>>>>>>>>>>> think it looks good already. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Guozhang >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Fri, Nov 16, 2018 at 4:21 PM Guozhang Wang < >>>>>>>>>>>>>> wangg...@gmail.com >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Thanks Florian! I will take a look at the PR. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> On Mon, Nov 12, 2018 at 2:44 PM Florian Hussonnois >> < >>>>>>>>>>>>>>>>>>>>> fhussonn...@gmail.com> >>>>>>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Hi Matthias, >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Sorry I was absent for a while. I have started a >> new >>>> PR >>>>>>>>>>>>>> for this >>>>>>>>>>>>>>>>>>> KIP. >>>>>>>>>>>>>>>>>>>> It >>>>>>>>>>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>>>>>>>>> still in progress for now. I'm working on it. >>>>>>>>>>>>>>>>>>>>>>> https://github.com/apache/kafka/pull/5909 >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Le ven. 19 oct. 2018 à 20:13, Matthias J. Sax < >>>>>>>>>>>>>>>>>>> matth...@confluent.io> >>>>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>>>>>> écrit : >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> What is the status of this KIP? >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> -Matthias >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> On 7/19/18 5:17 PM, Guozhang Wang wrote: >>>>>>>>>>>>>>>>>>>>>>>>> Hello Florian, >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> Sorry for being late... Found myself keep >>>> apologizing >>>>>>>>>>>>>> for late >>>>>>>>>>>>>>>>>>>>> replies >>>>>>>>>>>>>>>>>>>>>>>>> these days. But I do want to push this KIP's >>>> progress >>>>>>>>>>>>>> forward >>>>>>>>>>>>>>>>>>> as I >>>>>>>>>>>>>>>>>>>>>>> see it >>>>>>>>>>>>>>>>>>>>>>>>> very important and helpful feature for >>>> extensibility. >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> About the exceptions, I've gone through them and >>>>>>>>>>>>>> hopefully it >>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>>>>>> an >>>>>>>>>>>>>>>>>>>>>>>>> exhaustive list: >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> 1. KTable#toStream() >>>>>>>>>>>>>>>>>>>>>>>>> 2. KStream#merge(KStream) >>>>>>>>>>>>>>>>>>>>>>>>> 3. KStream#process() / transform() / >>>> transformValues() >>>>>>>>>>>>>>>>>>>>>>>>> 4. KGroupedTable / KGroupedStream#count() >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> Here's my reasoning: >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> * It is okay not letting users to override the >>> name >>>>> for >>>>>>>>>>>>>> 1/2, >>>>>>>>>>>>>>>>>>> since >>>>>>>>>>>>>>>>>>>>>>> they >>>>>>>>>>>>>>>>>>>>>>>> are >>>>>>>>>>>>>>>>>>>>>>>>> too trivial to be useful for debugging, plus >> their >>>>>>>>>>>>>> processor >>>>>>>>>>>>>>>>>>> names >>>>>>>>>>>>>>>>>>>>>>> would >>>>>>>>>>>>>>>>>>>>>>>>> not determine any related topic / store names. >>>>>>>>>>>>>>>>>>>>>>>>> * For 3, I'd vote for adding overloaded >> functions >>>> with >>>>>>>>>>>>>> Named. >>>>>>>>>>>>>>>>>>>>>>>>> * For 4, if users really want to name the >>> processor >>>>> she >>>>>>>>>>>>>> can >>>>>>>>>>>>>>> call >>>>>>>>>>>>>>>>>>>>>>>>> aggregate() instead, so I think it is okay to >> skip >>>>> this >>>>>>>>>>>>>> case. >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> Guozhang >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> On Fri, Jul 6, 2018 at 3:06 PM, Florian >>> Hussonnois < >>>>>>>>>>>>>>>>>>>>>>>> fhussonn...@gmail.com> >>>>>>>>>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> Hi, >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> The option #3 seems to be a good alternative >> and >>> I >>>>> find >>>>>>>>>>>>>> the >>>>>>>>>>>>>>> API >>>>>>>>>>>>>>>>>>>>> more >>>>>>>>>>>>>>>>>>>>>>>>>> elegant (thanks John). >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> But, we still have the need to overload some >>>> methods >>>>>>>>>>>>>> either >>>>>>>>>>>>>>>>>>>> because >>>>>>>>>>>>>>>>>>>>>>>> they do >>>>>>>>>>>>>>>>>>>>>>>>>> not accept an action instance or because they >> are >>>>>>>>>>>>>> translated >>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>> multiple >>>>>>>>>>>>>>>>>>>>>>>>>> processors. >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> For example, this is the case for methods >>> branch() >>>>> and >>>>>>>>>>>>>>> merge(). >>>>>>>>>>>>>>>>>>>> We >>>>>>>>>>>>>>>>>>>>>>> could >>>>>>>>>>>>>>>>>>>>>>>>>> introduce a new interface Named (or maybe a >>>> different >>>>>>>>>>>>>> name ?) >>>>>>>>>>>>>>>>>>>> with >>>>>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>>>>>>> method >>>>>>>>>>>>>>>>>>>>>>>>>> name(). All action interfaces could extend this >>> one >>>>> to >>>>>>>>>>>>>>>>>>> implement >>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>> option >>>>>>>>>>>>>>>>>>>>>>>>>> 3). >>>>>>>>>>>>>>>>>>>>>>>>>> This would result by having the following >>> overloads >>>>> : >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> Stream<K, V> merge(final Named name, final >>>> KStream<K, >>>>>>> V> >>>>>>>>>>>>>>>>>>> stream); >>>>>>>>>>>>>>>>>>>>>>>>>> KStream<K, V>[] branch(final Named name, final >>>>>>>>>>>>>> Predicate<? >>>>>>>>>>>>>>>>>>> super >>>>>>>>>>>>>>>>>>>>> K, ? >>>>>>>>>>>>>>>>>>>>>>>> super >>>>>>>>>>>>>>>>>>>>>>>>>> V>... predicates) >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> N.B : The list above is not exhaustive >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> --------- >>>>>>>>>>>>>>>>>>>>>>>>>> user's code will become : >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> KStream<String, Integer> stream = >>>>>>>>>>>>>>>>>>> builder.stream("test"); >>>>>>>>>>>>>>>>>>>>>>>>>> KStream<String, Integer>[] branches = >>>>>>>>>>>>>>>>>>>>>>>>>> >>> stream.branch(Named.with("BRANCH-STREAM-ON-VALUE"), >>>>>>>>>>>>>>>>>>>>>>>>>> >>>> Predicate.named("STREAM-PAIR-VALUE", >>>>>>>>>>>>>> (k, v) >>>>>>>>>>>>>>> -> >>>>>>>>>>>>>>>>>>> v >>>>>>>>>>>>>>>>>>>> % >>>>>>>>>>>>>>>>>>>>> 2 >>>>>>>>>>>>>>>>>>>>>>> == >>>>>>>>>>>>>>>>>>>>>>>>>> 0), >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>> Predicate.named("STREAM-IMPAIR-VALUE", >>>>>>>>>>>>>> (k, v) >>>>>>>>>>>>>>>>>>> -> >>>>>>>>>>>>>>>>>>>> v >>>>>>>>>>>>>>>>>>>>> % >>>>>>>>>>>>>>>>>>>>>>> 2 >>>>>>>>>>>>>>>>>>>>>>>> != >>>>>>>>>>>>>>>>>>>>>>>>>> 0)); >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> branches[0].to("pair"); >>>>>>>>>>>>>>>>>>>>>>>>>> branches[1].to("impair"); >>>>>>>>>>>>>>>>>>>>>>>>>> --------- >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> This is a mix of the options 3) and 1) >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> Le ven. 6 juil. 2018 à 22:58, Guozhang Wang < >>>>>>>>>>>>>>>>>>> wangg...@gmail.com> >>>>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>>>>>>> écrit : >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> Hi folks, just to summarize the options we >> have >>> so >>>>>>> far: >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Add a new "as" for KTable / KStream, plus >>>> adding >>>>>>> new >>>>>>>>>>>>>>> fields >>>>>>>>>>>>>>>>>>>> for >>>>>>>>>>>>>>>>>>>>>>>>>>> operators-returns-void control objects (the >>>> current >>>>>>>>>>>>>> wiki's >>>>>>>>>>>>>>>>>>>>>>> proposal). >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> Pros: no more overloads. >>>>>>>>>>>>>>>>>>>>>>>>>>> Cons: a bit departing with the current >>> high-level >>>>> API >>>>>>>>>>>>>> design >>>>>>>>>>>>>>>>>>> of >>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>> DSL, >>>>>>>>>>>>>>>>>>>>>>>>>>> plus, the inconsistency between >>>>> operators-returns-void >>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>>>>>>>>>> operators-not-return-voids. >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> 2) Add overloaded functions for all operators, >>>> that >>>>>>>>>>>>>> accepts >>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>>> new >>>>>>>>>>>>>>>>>>>>>>>> control >>>>>>>>>>>>>>>>>>>>>>>>>>> object "Described". >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> Pros: consistent with current APIs. >>>>>>>>>>>>>>>>>>>>>>>>>>> Cons: lots of overloaded functions to add. >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> 3) Add another default function in the >> interface >>>>>>>>>>>>>> (thank you >>>>>>>>>>>>>>>>>>> J8!) >>>>>>>>>>>>>>>>>>>>> as >>>>>>>>>>>>>>>>>>>>>>>> John >>>>>>>>>>>>>>>>>>>>>>>>>>> proposed. >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> Pros: no overloaded functions, no "Described". >>>>>>>>>>>>>>>>>>>>>>>>>>> Cons: do we lose lambda functions really >> (seems >>>> not >>>>> if >>>>>>>>>>>>>> we >>>>>>>>>>>>>>>>>>>> provide >>>>>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>>>>>>>>> "named" >>>>>>>>>>>>>>>>>>>>>>>>>>> for each func)? Plus "Described" may be more >>>>>>> extensible >>>>>>>>>>>>>>> than a >>>>>>>>>>>>>>>>>>>>>>> single >>>>>>>>>>>>>>>>>>>>>>>>>>> `String`. >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> My principle of considering which one is >> better >>>>>>> depends >>>>>>>>>>>>>>>>>>>> primarily >>>>>>>>>>>>>>>>>>>>> on >>>>>>>>>>>>>>>>>>>>>>>> "how >>>>>>>>>>>>>>>>>>>>>>>>>>> to make advanced users easily use the >> additional >>>>> API, >>>>>>>>>>>>>> while >>>>>>>>>>>>>>>>>>>>> keeping >>>>>>>>>>>>>>>>>>>>>>> it >>>>>>>>>>>>>>>>>>>>>>>>>>> hidden from normal users who do not care at >>> all". >>>>> For >>>>>>>>>>>>>> that >>>>>>>>>>>>>>>>>>>>> purpose I >>>>>>>>>>>>>>>>>>>>>>>>>> think >>>>>>>>>>>>>>>>>>>>>>>>>>> 3) > 1) > 2). >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> One caveat though, is that changing the >>> interface >>>>>>>>>>>>>> would not >>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>>>>>>>>>>>>> binary-compatible though source-compatible, >>> right? >>>>>>> I.e. >>>>>>>>>>>>>>> users >>>>>>>>>>>>>>>>>>>> need >>>>>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>> recompile their code though no changes needed. >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> Another note: for 3), if we really want to >> keep >>>>>>>>>>>>>>> extensibility >>>>>>>>>>>>>>>>>>> of >>>>>>>>>>>>>>>>>>>>>>>>>> Described >>>>>>>>>>>>>>>>>>>>>>>>>>> we could do sth. like: >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> --------- >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> public interface Predicate<K, V> { >>>>>>>>>>>>>>>>>>>>>>>>>>> // existing method >>>>>>>>>>>>>>>>>>>>>>>>>>> boolean test(final K key, final V value); >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> // new default method adds the ability to >>> name >>>>> the >>>>>>>>>>>>>>>>>>> predicate >>>>>>>>>>>>>>>>>>>>>>>>>>> default Described described() { >>>>>>>>>>>>>>>>>>>>>>>>>>> return new Described(null); >>>>>>>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> ---------- >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> where user's code becomes: >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> stream.filter(named("key", (k, v) -> true)); >>> // >>>>> note >>>>>>>>>>>>>>> `named` >>>>>>>>>>>>>>>>>>>> now >>>>>>>>>>>>>>>>>>>>>>> just >>>>>>>>>>>>>>>>>>>>>>>>>>> sets a Described("key") in "described()". >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> stream.filter(described(Described.as("key", /* >>> any >>>>>>>>>>>>>> other >>>>>>>>>>>>>>> fancy >>>>>>>>>>>>>>>>>>>>>>>>>> parameters >>>>>>>>>>>>>>>>>>>>>>>>>>> in the future*/), (k, v) -> true)); >>>>>>>>>>>>>>>>>>>>>>>>>>> ---------- >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> I feel it is not much likely that we'd need to >>>>> extend >>>>>>>>>>>>>> it >>>>>>>>>>>>>>>>>>> further >>>>>>>>>>>>>>>>>>>>> in >>>>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>> future, so just a `String` would be good >> enough. >>>> But >>>>>>>>>>>>>> just >>>>>>>>>>>>>>>>>>>> listing >>>>>>>>>>>>>>>>>>>>>>> all >>>>>>>>>>>>>>>>>>>>>>>>>>> possibilities here. >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> Guozhang >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> On Fri, Jul 6, 2018 at 8:19 AM, John Roesler < >>>>>>>>>>>>>>>>>>> j...@confluent.io >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Florian, >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry I'm late to the party, but I missed the >>>>> message >>>>>>>>>>>>>>>>>>>> originally. >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> Regarding the names, it's probably a good >> idea >>> to >>>>>>>>>>>>>> stick to >>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>> same >>>>>>>>>>>>>>>>>>>>>>>>>>>> character set we're currently using: letters, >>>>>>>>>>>>>> numbers, and >>>>>>>>>>>>>>>>>>>>> hyphens. >>>>>>>>>>>>>>>>>>>>>>>> The >>>>>>>>>>>>>>>>>>>>>>>>>>>> names are used in Kafka topics, files and >>>> folders, >>>>>>> and >>>>>>>>>>>>>>>>>>> RocksDB >>>>>>>>>>>>>>>>>>>>>>>>>> databases, >>>>>>>>>>>>>>>>>>>>>>>>>>>> and we also need them to work with the file >>>> systems >>>>>>> of >>>>>>>>>>>>>>>>>>> Windows, >>>>>>>>>>>>>>>>>>>>>>> Linux, >>>>>>>>>>>>>>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>>>>>>>>>>> MacOS. My opinion is that with a situation >> like >>>>> that, >>>>>>>>>>>>>> it's >>>>>>>>>>>>>>>>>>>> better >>>>>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>>>>>>>>>>>>>> conservative. It might also be a good idea to >>>>> impose >>>>>>>>>>>>>> an >>>>>>>>>>>>>>> upper >>>>>>>>>>>>>>>>>>>>>>> limit on >>>>>>>>>>>>>>>>>>>>>>>>>>> name >>>>>>>>>>>>>>>>>>>>>>>>>>>> length to avoid running afoul of any of those >>>>>>> systems. >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> --- >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> It seems like there's a small debate between >> 1) >>>>>>>>>>>>>> adding a >>>>>>>>>>>>>>> new >>>>>>>>>>>>>>>>>>>>>>> method to >>>>>>>>>>>>>>>>>>>>>>>>>>>> KStream (and maybe KTable) to modify its name >>>> after >>>>>>>>>>>>>> the >>>>>>>>>>>>>>> fact, >>>>>>>>>>>>>>>>>>>> or >>>>>>>>>>>>>>>>>>>>> 2) >>>>>>>>>>>>>>>>>>>>>>>>>>>> piggy-backing on the config objects where >> they >>>>> exist >>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>> adding >>>>>>>>>>>>>>>>>>>>> one >>>>>>>>>>>>>>>>>>>>>>>>>> where >>>>>>>>>>>>>>>>>>>>>>>>>>>> they don't. To me, #2 is the better >> alternative >>>>> even >>>>>>>>>>>>>> though >>>>>>>>>>>>>>>>>>> it >>>>>>>>>>>>>>>>>>>>>>>> produces >>>>>>>>>>>>>>>>>>>>>>>>>>>> more overloads and may be a bit awkward in >>>> places. >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> The reason is simply that #1 is a high-level >>>>>>>>>>>>>> departure from >>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>>> graph-building paradigm we're using in the >> DSL. >>>>>>>>>>>>>> Consider: >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> Graph.node1(config).node2(config) >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> vs >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> Graph.node1().config().node2().config() >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> We could have done either, but we picked the >>>>> former. >>>>>>> I >>>>>>>>>>>>>>> think >>>>>>>>>>>>>>>>>>>> it's >>>>>>>>>>>>>>>>>>>>>>>>>>> probably >>>>>>>>>>>>>>>>>>>>>>>>>>>> a good goal to try and stick to it so that >>>>> developers >>>>>>>>>>>>>> can >>>>>>>>>>>>>>>>>>>> develop >>>>>>>>>>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>>>>>>>>>> rely >>>>>>>>>>>>>>>>>>>>>>>>>>>> on their instincts for how the DSL will >> behave. >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> I do want to present one alternative to >> adding >>>> new >>>>>>>>>>>>>> config >>>>>>>>>>>>>>>>>>>>> objects: >>>>>>>>>>>>>>>>>>>>>>> we >>>>>>>>>>>>>>>>>>>>>>>>>> can >>>>>>>>>>>>>>>>>>>>>>>>>>>> just add a "name()" method to all our >> "action" >>>>>>>>>>>>>> interfaces. >>>>>>>>>>>>>>>>>>> For >>>>>>>>>>>>>>>>>>>>>>>> example, >>>>>>>>>>>>>>>>>>>>>>>>>>>> I'll demonstrate how we can add a "name" to >>>>> Predicate >>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>> then >>>>>>>>>>>>>>>>>>>>> use >>>>>>>>>>>>>>>>>>>>>>> it >>>>>>>>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>>> name a "KStream#filter" DSL operator: >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> public interface Predicate<K, V> { >>>>>>>>>>>>>>>>>>>>>>>>>>>> // existing method >>>>>>>>>>>>>>>>>>>>>>>>>>>> boolean test(final K key, final V value); >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> // new default method adds the ability to >>>> name >>>>>>> the >>>>>>>>>>>>>>>>>>>> predicate >>>>>>>>>>>>>>>>>>>>>>>>>>>> default String name() { >>>>>>>>>>>>>>>>>>>>>>>>>>>> return null; >>>>>>>>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> // new static factory method adds the >>> ability >>>>> to >>>>>>>>>>>>>> wrap >>>>>>>>>>>>>>>>>>>> lambda >>>>>>>>>>>>>>>>>>>>>>>>>>> predicates >>>>>>>>>>>>>>>>>>>>>>>>>>>> with a named predicate >>>>>>>>>>>>>>>>>>>>>>>>>>>> static <K, V> Predicate<K, V> named(final >>>>> String >>>>>>>>>>>>>> name, >>>>>>>>>>>>>>>>>>>> final >>>>>>>>>>>>>>>>>>>>>>>>>>>> Predicate<K, V> predicate) { >>>>>>>>>>>>>>>>>>>>>>>>>>>> return new Predicate<K, V>() { >>>>>>>>>>>>>>>>>>>>>>>>>>>> @Override >>>>>>>>>>>>>>>>>>>>>>>>>>>> public boolean test(final K key, >>>> final >>>>> V >>>>>>>>>>>>>>> value) { >>>>>>>>>>>>>>>>>>>>>>>>>>>> return predicate.test(key, >>>> value); >>>>>>>>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> @Override >>>>>>>>>>>>>>>>>>>>>>>>>>>> public String name() { >>>>>>>>>>>>>>>>>>>>>>>>>>>> return name; >>>>>>>>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>>>>>>>> }; >>>>>>>>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> Then, here's how it would look to use it: >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> // Anonymous predicates continue to work just >>>> fine >>>>>>>>>>>>>>>>>>>>>>>>>>>> stream.filter((k, v) -> true); >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> // Devs can swap in a Predicate that >> implements >>>> the >>>>>>>>>>>>>> name() >>>>>>>>>>>>>>>>>>>>> method. >>>>>>>>>>>>>>>>>>>>>>>>>>>> stream.filter(new Predicate<Object, >> Object>() { >>>>>>>>>>>>>>>>>>>>>>>>>>>> @Override >>>>>>>>>>>>>>>>>>>>>>>>>>>> public boolean test(final Object key, >> final >>>>>>> Object >>>>>>>>>>>>>>>>>>> value) { >>>>>>>>>>>>>>>>>>>>>>>>>>>> return true; >>>>>>>>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> @Override >>>>>>>>>>>>>>>>>>>>>>>>>>>> public String name() { >>>>>>>>>>>>>>>>>>>>>>>>>>>> return "hey"; >>>>>>>>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>>>>>>>> }); >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> // Or they can wrap their existing lambda >> using >>>> the >>>>>>>>>>>>>> static >>>>>>>>>>>>>>>>>>>>> factory >>>>>>>>>>>>>>>>>>>>>>>>>> method >>>>>>>>>>>>>>>>>>>>>>>>>>>> stream.filter(named("key", (k, v) -> true)); >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> Just a thought. >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> Overall, I think it's really valuable to be >>> able >>>> to >>>>>>>>>>>>>> name >>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>> processors, >>>>>>>>>>>>>>>>>>>>>>>>>>>> for all the reasons you mentioned in the KIP. >>> So >>>>>>>>>>>>>> thank you >>>>>>>>>>>>>>>>>>> for >>>>>>>>>>>>>>>>>>>>>>>>>>> introducing >>>>>>>>>>>>>>>>>>>>>>>>>>>> this! >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>>>>>>>>>>>>>>>> -John >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> On Thu, Jul 5, 2018 at 4:53 PM Florian >>>> Hussonnois < >>>>>>>>>>>>>>>>>>>>>>>>>> fhussonn...@gmail.com >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi, thank you very much for all you >>> suggestions. >>>>>>> I've >>>>>>>>>>>>>>>>>>> started >>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>> update >>>>>>>>>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>>>> KIP ( >>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>> https://cwiki.apache.org/confluence/display/KAFKA/KIP- >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>> 307%3A+Allow+to+define+custom+processor+names+with+KStreams+DSL >>>>>>>>>>>>>>>>>>>>>>>>>>>>> ). >>>>>>>>>>>>>>>>>>>>>>>>>>>>> Also, I propose to rename the Processed >> class >>>> into >>>>>>>>>>>>>>>>>>> Described - >>>>>>>>>>>>>>>>>>>>>>> this >>>>>>>>>>>>>>>>>>>>>>>>>>> will >>>>>>>>>>>>>>>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>>>>>>>>>>>>>>> more meaningful (but this is just a detail). >>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm OK to not enforcing uppercase for >> specific >>>>> names >>>>>>>>>>>>>> but >>>>>>>>>>>>>>>>>>>> should >>>>>>>>>>>>>>>>>>>>> we >>>>>>>>>>>>>>>>>>>>>>>>>>> allow >>>>>>>>>>>>>>>>>>>>>>>>>>>>> arbitrary names with whitespaces for >> example ? >>>>>>>>>>>>>> Currently, >>>>>>>>>>>>>>> I >>>>>>>>>>>>>>>>>>>>> can't >>>>>>>>>>>>>>>>>>>>>>>>>> tell >>>>>>>>>>>>>>>>>>>>>>>>>>> if >>>>>>>>>>>>>>>>>>>>>>>>>>>>> this can lead to some side effects ? >>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>> Le lun. 11 juin 2018 à 01:31, Matthias J. >> Sax >>> < >>>>>>>>>>>>>>>>>>>>>>> matth...@confluent.io >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>>>>>>>>>>>> écrit : >>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Just catching up on this thread. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I like the general idea. Couple of >> comments: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - I think that adding `Processed` (or >> maybe >>> a >>>>>>>>>>>>>> different >>>>>>>>>>>>>>>>>>>> name?) >>>>>>>>>>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valid proposal for stateless operators that >>>> only >>>>>>>>>>>>>> have a >>>>>>>>>>>>>>>>>>>> single >>>>>>>>>>>>>>>>>>>>>>>>>>> overload >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> atm. It would align with the overall API >>>> design. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - for all methods with multiple existing >>>>>>>>>>>>>> overloads, we >>>>>>>>>>>>>>> can >>>>>>>>>>>>>>>>>>>>>>>>>> consider >>>>>>>>>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> extend `Consumed`, `Produced`, >> `Materialized` >>>> etc >>>>>>>>>>>>>> to take >>>>>>>>>>>>>>>>>>> an >>>>>>>>>>>>>>>>>>>>>>>>>>> additional >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> processor name (not sure atm how elegant >> this >>>> is; >>>>>>> we >>>>>>>>>>>>>>> would >>>>>>>>>>>>>>>>>>>> need >>>>>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "play" with the API a little bit; the >>> advantage >>>>>>>>>>>>>> would be, >>>>>>>>>>>>>>>>>>>> that >>>>>>>>>>>>>>>>>>>>> we >>>>>>>>>>>>>>>>>>>>>>>>>> do >>>>>>>>>>>>>>>>>>>>>>>>>>>> not >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> add more overloads what seems to be key for >>>> this >>>>>>>>>>>>>> KIP) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - operators return void: while I agree >> that >>>> the >>>>>>>>>>>>>> "name >>>>>>>>>>>>>>>>>>> first" >>>>>>>>>>>>>>>>>>>>>>>>>>> chaining >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> idea is not very intuitive, it might still >>>> work, >>>>> if >>>>>>>>>>>>>> we >>>>>>>>>>>>>>> name >>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>> method >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> correctly (again, we would need to "play" >>> with >>>>> the >>>>>>>>>>>>>> API a >>>>>>>>>>>>>>>>>>>> little >>>>>>>>>>>>>>>>>>>>>>> bit >>>>>>>>>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>>>> see) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - for DSL operators that are translated to >>>>>>> multiple >>>>>>>>>>>>>>> nodes: >>>>>>>>>>>>>>>>>>>> it >>>>>>>>>>>>>>>>>>>>>>>>>> might >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> make sense to use the specified operator >> name >>>> as >>>>>>>>>>>>>> prefix >>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>>> add >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> reasonable suffixes. For example, a join >>>>> translates >>>>>>>>>>>>>> into >>>>>>>>>>>>>>> 5 >>>>>>>>>>>>>>>>>>>>>>>>>> operators >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> that could be name >>> "name-left-store-processor", >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "name-left-join-processor", >>>>>>>>>>>>>> "name-right-store-processor", >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "name-right-join-processor", and >>>>>>>>>>>>>>>>>>> "name-join-merge-processor" >>>>>>>>>>>>>>>>>>>>> (or >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> similar). Maybe just using numbers might >> also >>>>> work. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - I think, we should strip the number >>> suffixes >>>>> if >>>>>>>>>>>>>> a user >>>>>>>>>>>>>>>>>>>>>>> provides >>>>>>>>>>>>>>>>>>>>>>>>>>>> names >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - enforcing upper case seems to be tricky: >>> for >>>>>>>>>>>>>> example, >>>>>>>>>>>>>>> we >>>>>>>>>>>>>>>>>>>> do >>>>>>>>>>>>>>>>>>>>>>> not >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> enforce upper case for store names and we >>>> cannot >>>>>>>>>>>>>> easily >>>>>>>>>>>>>>>>>>>> change >>>>>>>>>>>>>>>>>>>>> it >>>>>>>>>>>>>>>>>>>>>>>>>> as >>>>>>>>>>>>>>>>>>>>>>>>>>> it >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> would break compatibility -- thus, for >>>>> consistency >>>>>>>>>>>>>>> reasons >>>>>>>>>>>>>>>>>>> we >>>>>>>>>>>>>>>>>>>>>>> might >>>>>>>>>>>>>>>>>>>>>>>>>>> not >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> want to do this >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - for better understand of the impact of >> the >>>>> KIP, >>>>>>>>>>>>>> it >>>>>>>>>>>>>>> would >>>>>>>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>>>>>>>>>>>> quite >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> helpful if you would list all method names >>> that >>>>> are >>>>>>>>>>>>>>>>>>> affected >>>>>>>>>>>>>>>>>>>> in >>>>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>> KIP >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (ie, list all newly added overloads) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -Matthias >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 5/31/18 6:40 PM, Guozhang Wang wrote: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Florian, >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Re 1: I think changing the KStreamImpl / >>>>>>>>>>>>>> KTableImpl to >>>>>>>>>>>>>>>>>>> allow >>>>>>>>>>>>>>>>>>>>>>>>>>>> modifying >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> processor name after the operator is fine >> as >>>>> long >>>>>>>>>>>>>> as we >>>>>>>>>>>>>>> do >>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>> check >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> again >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> when modifying that. In fact, we are >> having >>>> some >>>>>>>>>>>>>>> topology >>>>>>>>>>>>>>>>>>>>>>>>>>>> optimization >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> going on which may modify processor names >> in >>>> the >>>>>>>>>>>>>> final >>>>>>>>>>>>>>>>>>>>> topology >>>>>>>>>>>>>>>>>>>>>>>>>>>>> anyways ( >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://github.com/apache/kafka/pull/4983 >> ). >>>>>>>>>>>>>>> Semantically >>>>>>>>>>>>>>>>>>> I >>>>>>>>>>>>>>>>>>>>>>> think >>>>>>>>>>>>>>>>>>>>>>>>>>> it >>>>>>>>>>>>>>>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> easier to understand to developers than >>>>> "deciding >>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>> processor >>>>>>>>>>>>>>>>>>>>>>>>>>> name >>>>>>>>>>>>>>>>>>>>>>>>>>>>> for >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the next operator". >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Re 2: Yeah I'm thinking that for operators >>>> that >>>>>>>>>>>>>>> translates >>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>>> multiple >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> processor names, we can still use the >>> provided >>>>>>>>>>>>>> "hint" to >>>>>>>>>>>>>>>>>>>> name >>>>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> processor >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> names, e.g. for Joins we can name them as >>>>>>>>>>>>>>> `join-foo-this` >>>>>>>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> `join-foo-that` etc if user calls >>> `as("foo")`. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Re 3: The motivation I had about removing >>> the >>>>>>>>>>>>>> suffix is >>>>>>>>>>>>>>>>>>> that >>>>>>>>>>>>>>>>>>>>> it >>>>>>>>>>>>>>>>>>>>>>>>>> has >>>>>>>>>>>>>>>>>>>>>>>>>>>>> huge >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> restrictions on topology compatibilities: >>>>> consider >>>>>>>>>>>>>> if >>>>>>>>>>>>>>> user >>>>>>>>>>>>>>>>>>>>> code >>>>>>>>>>>>>>>>>>>>>>>>>>>> added a >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> new >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> operator, or library does some >> optimization >>> to >>>>>>>>>>>>>> remove >>>>>>>>>>>>>>> some >>>>>>>>>>>>>>>>>>>>>>>>>>> operators, >>>>>>>>>>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suffix indexing may be changed for a large >>>>> amount >>>>>>>>>>>>>> of the >>>>>>>>>>>>>>>>>>>>>>>>>> processor >>>>>>>>>>>>>>>>>>>>>>>>>>>>> names: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> this will in turn change the internal >> state >>>>> store >>>>>>>>>>>>>> names, >>>>>>>>>>>>>>>>>>> as >>>>>>>>>>>>>>>>>>>>> well >>>>>>>>>>>>>>>>>>>>>>>>>> as >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> internal topic names as well, making the >> new >>>>>>>>>>>>>> application >>>>>>>>>>>>>>>>>>>>>>> topology >>>>>>>>>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incompatible with the ones. One rationale >> I >>>> had >>>>>>>>>>>>>> about >>>>>>>>>>>>>>> this >>>>>>>>>>>>>>>>>>>> KIP >>>>>>>>>>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>>>>>>>>>>>>>> that >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> aligned this effort, moving forward we can >>>> allow >>>>>>>>>>>>>> users >>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>> customize >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> internal names so that they can still be >>>> reused >>>>>>>>>>>>>> even >>>>>>>>>>>>>>> with >>>>>>>>>>>>>>>>>>>>>>>>>> topology >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> changes >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (e.g. KIP-230), so I think removing the >>> suffix >>>>>>>>>>>>>> index >>>>>>>>>>>>>>> would >>>>>>>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>>>>>>>>>>>> more >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> applicable in the long run. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Guozhang >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Thu, May 31, 2018 at 3:08 PM, Florian >>>>>>>>>>>>>> Hussonnois < >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> fhussonn...@gmail.com> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi , >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Thank you very much for your feedback. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1/ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I agree that overloading most of the >>> methods >>>>> with >>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>>> Processed >>>>>>>>>>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>>>>>>>>>>>>> not >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ideal. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I've started modifying the KStream API >> and >>> I >>>>> got >>>>>>>>>>>>>> to the >>>>>>>>>>>>>>>>>>>> same >>>>>>>>>>>>>>>>>>>>>>>>>>>>> conclusion. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Also ading a new method directly to >>>> KStreamImpl >>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>>>> KTableImpl >>>>>>>>>>>>>>>>>>>>>>>>>>>> classes >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seems to be a better option. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> However a processor name cannot be >>> redefined >>>>>>> after >>>>>>>>>>>>>>>>>>> calling >>>>>>>>>>>>>>>>>>>> an >>>>>>>>>>>>>>>>>>>>>>>>>>>> operator >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (or >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> maybe I miss something in the code). >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> From my understanding, this will only set >>> the >>>>>>>>>>>>>> KStream >>>>>>>>>>>>>>>>>>> name >>>>>>>>>>>>>>>>>>>>>>>>>>> property >>>>>>>>>>>>>>>>>>>>>>>>>>>>> not >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> processor name previsouly added to the >>>> topology >>>>>>>>>>>>>>> builder - >>>>>>>>>>>>>>>>>>>>>>>>>> leading >>>>>>>>>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> InvalidTopology exception. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> So the new method should actually defines >>> the >>>>>>>>>>>>>> name of >>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>> next >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> processor : >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Below is an example : >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *stream.as <http://stream.as >>>>>>>>>>>>>>>>>>>>>>>>>>>> (Processed.name("MAPPE_TO_UPPERCASE")* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> * .map( (k, v) -> >> KeyValue.pair(k, >>>>>>>>>>>>>>>>>>>>> v.toUpperCase()))* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I think this approach could solve the >> cases >>>> for >>>>>>>>>>>>>> methods >>>>>>>>>>>>>>>>>>>>>>>>>> returning >>>>>>>>>>>>>>>>>>>>>>>>>>>>> void ? >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Regarding this new method we have two >>>> possible >>>>>>>>>>>>>>>>>>>>> implementations >>>>>>>>>>>>>>>>>>>>>>> : >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1. Adding a method like : >>> withName(String >>>>>>>>>>>>>>>>>>> processorName) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2. or adding a method accepting an >>>> Processed >>>>>>>>>>>>>> object >>>>>>>>>>>>>>> : >>>>>>>>>>>>>>>>>>>>>>>>>>>>> as(Processed). >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I think solution 2. is preferable as the >>>>>>> Processed >>>>>>>>>>>>>>> class >>>>>>>>>>>>>>>>>>>>> could >>>>>>>>>>>>>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> enriched >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> further (in futur). >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2/ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> As Guozhang said some operators add >>> internal >>>>>>>>>>>>>>> processors. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For example the branch() method create >> one >>>>>>>>>>>>>>> KStreamBranch >>>>>>>>>>>>>>>>>>>>>>>>>> processor >>>>>>>>>>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> route >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> records and one KStreamPassThrough >>> processor >>>>> for >>>>>>>>>>>>>> each >>>>>>>>>>>>>>>>>>>> branch. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In that situation only the parent >> processor >>>> can >>>>>>> be >>>>>>>>>>>>>>> named. >>>>>>>>>>>>>>>>>>>> For >>>>>>>>>>>>>>>>>>>>>>>>>>>> children >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> processors we could keep the current >>>> behaviour >>>>>>>>>>>>>> that >>>>>>>>>>>>>>> add a >>>>>>>>>>>>>>>>>>>>>>> suffix >>>>>>>>>>>>>>>>>>>>>>>>>>>> (i.e >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> KSTREAM-BRANCHCHILD-) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> This also the case for the join() method >>> that >>>>>>>>>>>>>> result to >>>>>>>>>>>>>>>>>>>>> adding >>>>>>>>>>>>>>>>>>>>>>>>>>>>> multiple >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> processors to the topology (windowing, >>>>> left/right >>>>>>>>>>>>>> joins >>>>>>>>>>>>>>>>>>>> and a >>>>>>>>>>>>>>>>>>>>>>>>>>> merge >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> processor). >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I think, like for the branch method users >>>> could >>>>>>>>>>>>>> only >>>>>>>>>>>>>>>>>>>> define a >>>>>>>>>>>>>>>>>>>>>>>>>>>>> processor >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> name prefix. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3/ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I think we should still added a suffix >>> like >>>>>>>>>>>>>>>>>>> "-0000000000" >>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>>>> processor >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> name and enforce uppercases as this will >>> keep >>>>>>> some >>>>>>>>>>>>>>>>>>>>> consistency >>>>>>>>>>>>>>>>>>>>>>>>>>> with >>>>>>>>>>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ones generated by the API. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4/ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Yes, the KTable interface should be >>> modified >>>>> like >>>>>>>>>>>>>>> KStream >>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>> allow >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> custom >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> processor names definition. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Le jeu. 31 mai 2018 à 19:18, Damian Guy < >>>>>>>>>>>>>>>>>>>>> damian....@gmail.com> >>>>>>>>>>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>>>>>>>>>>>> écrit >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> : >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Florian, >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Thanks for the KIP. What about KTable >> and >>>>> other >>>>>>>>>>>>>> DSL >>>>>>>>>>>>>>>>>>>>>>> interfaces? >>>>>>>>>>>>>>>>>>>>>>>>>>>> Will >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> they >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> not want to be able to do the same >> thing? >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> It would be good to see a complete set >> of >>>> the >>>>>>>>>>>>>> public >>>>>>>>>>>>>>> API >>>>>>>>>>>>>>>>>>>>>>>>>> changes. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Cheers, >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Damian >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Wed, 30 May 2018 at 19:45 Guozhang >>> Wang < >>>>>>>>>>>>>>>>>>>>>>> wangg...@gmail.com >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hello Florian, >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Thanks for the KIP. I have some meta >>>>> feedbacks >>>>>>>>>>>>>> on the >>>>>>>>>>>>>>>>>>>>>>>>>> proposal: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1. You mentioned that this `Processed` >>>> object >>>>>>>>>>>>>> will be >>>>>>>>>>>>>>>>>>>> added >>>>>>>>>>>>>>>>>>>>>>>>>> to a >>>>>>>>>>>>>>>>>>>>>>>>>>>> new >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> overloaded variant of all the stateless >>>>>>>>>>>>>> operators, >>>>>>>>>>>>>>> what >>>>>>>>>>>>>>>>>>>>> about >>>>>>>>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> stateful >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> operators? Would like to hear your >>> opinions >>>>> if >>>>>>>>>>>>>> you >>>>>>>>>>>>>>> have >>>>>>>>>>>>>>>>>>>>>>>>>> thought >>>>>>>>>>>>>>>>>>>>>>>>>>>>> about >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> that: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> note for stateful operators they will >>>> usually >>>>>>> be >>>>>>>>>>>>>>> mapped >>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>>> multiple >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> processor node names, so we probably >> need >>>> to >>>>>>>>>>>>>> come up >>>>>>>>>>>>>>>>>>> with >>>>>>>>>>>>>>>>>>>>>>> some >>>>>>>>>>>>>>>>>>>>>>>>>>>> ways >>>>>>>>>>>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> define all their names. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2. I share the same concern with Bill >> as >>>> for >>>>>>>>>>>>>> adding >>>>>>>>>>>>>>>>>>> lots >>>>>>>>>>>>>>>>>>>> of >>>>>>>>>>>>>>>>>>>>>>>>>> new >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> overload >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> functions into the stateless operators, >>> as >>>> we >>>>>>>>>>>>>> have >>>>>>>>>>>>>>> just >>>>>>>>>>>>>>>>>>>>> spent >>>>>>>>>>>>>>>>>>>>>>>>>>>> quite >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> some >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> effort in trimming them since 1.0.0 >>>> release. >>>>> If >>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>> goal >>>>>>>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>>> just >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> provide >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> some "hints" on the generated processor >>>> node >>>>>>>>>>>>>> names, >>>>>>>>>>>>>>> not >>>>>>>>>>>>>>>>>>>>>>>>>> strictly >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> enforcing >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the exact names that to be generated, >>> then >>>>> how >>>>>>>>>>>>>> about >>>>>>>>>>>>>>> we >>>>>>>>>>>>>>>>>>>>> just >>>>>>>>>>>>>>>>>>>>>>>>>>> add a >>>>>>>>>>>>>>>>>>>>>>>>>>>>> new >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> function to `KStream` and `KTable` >>> classes >>>>>>> like: >>>>>>>>>>>>>>>>>>>>>>>>>>> "as(Processed)", >>>>>>>>>>>>>>>>>>>>>>>>>>>>> with >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> semantics as "the latest operators that >>>>>>>>>>>>>> generate this >>>>>>>>>>>>>>>>>>>>> KStream >>>>>>>>>>>>>>>>>>>>>>>>>> / >>>>>>>>>>>>>>>>>>>>>>>>>>>>> KTable >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> will >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> be named accordingly to this hint". >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The only caveat, is that for all >>> operators >>>>> like >>>>>>>>>>>>>>>>>>>>> `KStream#to` >>>>>>>>>>>>>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> `KStream#print` that returns void, this >>>>>>>>>>>>>> alternative >>>>>>>>>>>>>>>>>>> would >>>>>>>>>>>>>>>>>>>>> not >>>>>>>>>>>>>>>>>>>>>>>>>>>> work. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> But >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the current operators: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a. KStream#print, >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> b. KStream#foreach, >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> c. KStream#to, >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> d. KStream#process >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I personally felt that except >>>>> `KStream#process` >>>>>>>>>>>>>> users >>>>>>>>>>>>>>>>>>>> would >>>>>>>>>>>>>>>>>>>>>>>>>> not >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> usually >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> bother to override their names, and for >>>>>>>>>>>>>>>>>>> `KStream#process` >>>>>>>>>>>>>>>>>>>>> we >>>>>>>>>>>>>>>>>>>>>>>>>>> could >>>>>>>>>>>>>>>>>>>>>>>>>>>>> add >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> an >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> overload variant with the additional >>>>> Processed >>>>>>>>>>>>>>> object. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3. In your example, the processor names >>> are >>>>>>>>>>>>>> still >>>>>>>>>>>>>>> added >>>>>>>>>>>>>>>>>>>>> with >>>>>>>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>>>>>>>>>>>> suffix >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> like >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -0000000000", is this intentional? If >>> yes, >>>>> why >>>>>>>>>>>>>> (I >>>>>>>>>>>>>>>>>>> thought >>>>>>>>>>>>>>>>>>>>>>> with >>>>>>>>>>>>>>>>>>>>>>>>>>>> user >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> specified processor name hints we will >>> not >>>>> add >>>>>>>>>>>>>> suffix >>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>>> distinguish >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> different nodes of the same type any >>> more)? >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Guozhang >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Tue, May 29, 2018 at 6:47 AM, Bill >>>> Bejeck >>>>> < >>>>>>>>>>>>>>>>>>>>>>>>>> bbej...@gmail.com >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi Florian, >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Thanks for the KIP. I think being >> able >>> to >>>>> add >>>>>>>>>>>>>> more >>>>>>>>>>>>>>>>>>>>> context >>>>>>>>>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> processor names would be useful. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I like the idea of adding a >>>>>>>>>>>>>> "withProcessorName" to >>>>>>>>>>>>>>>>>>>>> Produced, >>>>>>>>>>>>>>>>>>>>>>>>>>>>> Consumed >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Joined. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> But instead of adding the "Processed" >>>>>>>>>>>>>> parameter to a >>>>>>>>>>>>>>>>>>>> large >>>>>>>>>>>>>>>>>>>>>>>>>>>>> percentage >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the methods, which would result in >>>>> overloaded >>>>>>>>>>>>>>> methods >>>>>>>>>>>>>>>>>>>>> (which >>>>>>>>>>>>>>>>>>>>>>>>>> we >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> removed >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> quite a bit with KIP-182) what do you >>>> think >>>>> of >>>>>>>>>>>>>>> adding >>>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>>>>>>>>> method >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to the AbstractStream class >>>> "withName(String >>>>>>>>>>>>>>>>>>>>>>> processorName)"? >>>>>>>>>>>>>>>>>>>>>>>>>>> BTW >>>>>>>>>>>>>>>>>>>>>>>>>>>>> I"m >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> not >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> married to the method name, it's the >>> best >>>> I >>>>>>>>>>>>>> can do >>>>>>>>>>>>>>> off >>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>> top >>>>>>>>>>>>>>>>>>>>>>>>>>> of >>>>>>>>>>>>>>>>>>>>>>>>>>>>> my >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> head. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For the methods that return void, we'd >>>> have >>>>> to >>>>>>>>>>>>>> add a >>>>>>>>>>>>>>>>>>>>>>>>>> parameter, >>>>>>>>>>>>>>>>>>>>>>>>>>>> but >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> that >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> would at least cut down on the number >> of >>>>>>>>>>>>>> overloaded >>>>>>>>>>>>>>>>>>>>> methods >>>>>>>>>>>>>>>>>>>>>>>>>> in >>>>>>>>>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> API. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Just my 2 cents. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Bill >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Sun, May 27, 2018 at 4:13 PM, >> Florian >>>>>>>>>>>>>> Hussonnois >>>>>>>>>>>>>>> < >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> fhussonn...@gmail.com >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hi, >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I would like to start a new >> discussion >>> on >>>>>>>>>>>>>> following >>>>>>>>>>>>>>>>>>>> KIP : >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >> https://cwiki.apache.org/confluence/display/KAFKA/KIP- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>> 307%3A+Allow+to+define+custom+processor+names+with+KStreams+DSL >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> This is still a draft. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Looking forward for your feedback. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Florian HUSSONNOIS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -- Guozhang >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Florian HUSSONNOIS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>>>>>>>> Florian HUSSONNOIS >>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>>>>>> -- Guozhang >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>>>>> Florian HUSSONNOIS >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>> Florian HUSSONNOIS >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>> -- Guozhang >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>> -- Guozhang >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>> -- Guozhang >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Florian HUSSONNOIS >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> -- Guozhang >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> -- Guozhang >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> -- Guozhang >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>> >>>>> >>>> >>> >> >> >> -- >> Florian HUSSONNOIS >> > >
signature.asc
Description: OpenPGP digital signature