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
>>
> 
> 

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to