I was reading the KIP again, and there are still some open question and inconsistencies:
For example for `KGroupedStream#count(Named)` the KIP says, that only the processor will be named, while the state store name will be `PREFIX + COUNT` (ie, an auto-generated name). Additionally, for `KGroupedStream#count(Named, Materialized)` the processor will be named according to `Named` and the store will be named according to `Materialized.as()`. So far so good. It implies that naming the processor and naming the store are independent. (This pattern is applied to all aggregation functions, for KStream and KTable). However, for `KTable#filter(Predicate, Named)` the KIP says, the processor name and the store name are set. This sound wrong (ie, inconsistent with the first paragraph from above), because there is also `KTable#filter(Predicate, Named, Materialized)`. Also note, for the first operator, the store might not be materialized to at all. (This issue is there for all KTable operators -- stateless and stateful). Finally, there is the following statement in the KIP: > Also, note that for all methods accepting a Materialized argument, if no > state store named is provided then the node named will be used to generate a > one. The state store name will be the node name suffixed with "-table". This contradict the non-naming of stores from the very beginning. Also, the KIP still contains the question about `join(GlobalKTable, KeyValueMapper, ValueJoiner)` and `leftJoin(GlobalKTable, KeyValueMapper, ValueJoiner)`. I think a consistent approach would be to add one overload each that takes a `Named` parameter. Thoughts? -Matthias On 1/17/19 2:56 PM, Bill Bejeck wrote: > +1 for me on Guozhang's proposal for changes to Joined. > > Thanks, > Bill > > On Thu, Jan 17, 2019 at 5:55 PM Matthias J. Sax <matth...@confluent.io> > wrote: > >> 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