Hi Kirk,

Thanks for reviewing the KIP and providing detailed feedback.

KT4: I would prefer to keep the name as `timeout` since its type is
`Duration`, and `Duration` provides various ways to create an instance, not
just using milliseconds.
KT5: Good point! I’ve added some additional description about the behavior
when `null` is passed as `CloseOptions`.
KT6: I would like to retain the use of `Optional` for this case, as it
helps differentiate between the default settings and user-defined ones. It
also provides better semantics and null-safety. Let me know if you have any
further thoughts on this.
KT7: I agree that enums offer better readability and semantics. I've
applied this change and slightly adjusted the name to
`GroupMembershipOperations` for precision.
KT8: Thanks for pointing this out. I've corrected the test plan to specify
that the default timeout is 30 seconds instead of `Long.MAX_VALUE`.

Lastly, I’ve also added content to the "Compatibility, Deprecation, and
Migration Plan" section, as we are planning to deprecate the
`Consumer#close(Duration)` method. Please take a look and let me know what
you think.

Best,
TengYao

Andrew Schofield <andrew_schofield_j...@outlook.com> 於 2024年10月1日 週二
下午2:41寫道:

> +1 from me on the fluent API using the `with` prefix too.
>
> Thanks,
> Andrew
>
> ________________________________________
> From: TengYao Chi <kiting...@gmail.com>
> Sent: 01 October 2024 05:23
> To: dev@kafka.apache.org <dev@kafka.apache.org>
> Subject: Re: [DISCUSS] KIP-1092: Extend Consumer#close with an option to
> leave the group or not
>
> Hello everyone,
>
> I'm also +1 on using the fluent API and having the `with` prefix in setter
> method names.
>
> Regarding Matthias' point, I agree with Sophie that we should keep the
> `CloseOptions` classes separate.
> These two `CloseOptions` serve different purposes, and while they may
> occasionally share some similarities at the moment, keeping them separate
> allows more flexibility for their own future changes. This way, each class
> can evolve independently based on the specific needs of the Consumer and
> Kafka Streams without introducing unnecessary complexity.
>
> Best,
> TengYao
>
> Matthias J. Sax <mj...@apache.org> 於 2024年10月1日 週二 上午7:38寫道:
>
> > Sophie, yes, that a fair summary, and yes, it was only an alternative
> > idea for the case that people think, allowing to disable leave-group
> > request for the plain consumer is not desirable. Seems we are actually
> > on the same page.
> >
> > (And yes, it was meant for this thread, not KIP-1094...)
> >
> >
> >
> > On 9/30/24 4:32 PM, Matthias J. Sax wrote:
> > > Kirk,
> > >
> > > I think good API design principle is to expose the minimum require API
> > > to users, and users don't need getters, that's why we don't have any
> > > getters in the KS config object classes. Getters are only needed
> > > internally.
> > >
> > >  From an impl POV, the internal member can be either (1)
> package-private
> > > to allow direct access within the same package, or (2) protected in
> > > combination with an internal sub-class in an internal package to add
> the
> > > necessary getters. As an example cf `Consumed` and `ConsumedInternal`
> > >
> > >
> >
> https://github.com/apache/kafka/blob/trunk/streams/src/main/java/org/apache/kafka/streams/kstream/Consumed.java
> > >
> > >
> >
> https://github.com/apache/kafka/blob/trunk/streams/src/main/java/org/apache/kafka/streams/kstream/internals/ConsumedInternal.java
> > >
> > > It provides a clean separation of user-facing public API, vs internal
> > APIs.
> > >
> > >
> > >
> > > For `timeout()` given that it takes a `Duration` argument (not a
> > > `long`), I believe the current name is correct?
> > >
> > >
> > > The like the idea of using an enum for send-leave-group request flag.
> > >
> > >
> > > For `Optional`, if we remove the public getters, the question goes
> away.
> > >
> > >
> > >
> > > About merging both `CloseOptions`: fine with me to keep them separated.
> > > Was just an idea :)
> > >
> > >
> > >
> > > -Matthias
> > >
> > >
> > > On 9/30/24 3:14 PM, Sophie Blee-Goldman wrote:
> > >> +1 to using the fluent API and including "with" in the setter names.
> > >>
> > >> I also think Matthias raised a good point, that maybe it would be a
> good
> > >> time to "fix" this issue in the CloseOptions for the
> KafkaStreams#close
> > >> method, to conform to this API format. As for his other "random idea"
> > >> about
> > >> combining the two: Personally I would prefer to keep a separate
> > >> CloseOptions class for the Consumer vs for Kafka Streams, since they
> > will
> > >> not necessarily always have the same exact semantics and parameters.
> > Even
> > >> if the API ends up looking more or less the same right now -- although
> > >> consider that the "default" behavior is different for the consumer vs
> > >> Kafka
> > >> Streams, if leaveGroup is not specified in the CloseOptions then the
> > >> consumer will opt to leave the group in some cases whereas Streams
> never
> > >> will. So already there is some difference between the Consumer and
> > >> Streams
> > >> CloseOptions, so I'd rather not combine them
> > >>
> > >> On Mon, Sep 30, 2024 at 11:16 AM Chia-Ping Tsai <chia7...@gmail.com>
> > >> wrote:
> > >>
> > >>>> Overall, the "static method builder" pattern seems better to me, and
> > >>> thus I would prefer to make it the "gold standard" and we can see
> > >>> what  we
> > >>> can do for `Admin API` mid/long term?
> > >>>
> > >>> Since we want to avoid complicated compatibility issues, adding a
> > static
> > >>> method builder to Admin options seems more acceptable.
> > >>>
> > >>> However, the naming convention for the "setter" method might be a
> > >>> concern.
> > >>> Kafka Streams (KS) uses "withXXX," while Admin options do not include
> > >>> the
> > >>> "with" prefix. Additionally, the RPC requests follow the setXXX
> naming
> > >>> convention.
> > >>>
> > >>> I’m unsure if this is the right time to align the fluent pattern
> naming
> > >>> across the entire Kafka project, but it would be great if we could
> > >>> reach a
> > >>> consensus on "gold standard".
> > >>>
> > >>> I'm +1 to using the static method builder and `with` prefix due to
> > >>> following advantages.
> > >>> -
> > >>>
> > >>> 1. A static method builder allows making the constructor private,
> > >>> which can
> > >>> prevent unintended inheritance
> > >>> -
> > >>>
> > >>> 2. The "with" prefix makes it easier to search for setters within the
> > >>> option class
> > >>>
> > >>> Any feedback?
> > >>>
> > >>>> Btw: I was also wondering, if we should re-use the new consumer
> > >>> `CloseOption` class for `KafkaStreams#close()` and deprecate the KS
> > >>> `CloseOption`
> > >>> class? Not sure. Just another "random" idea.
> > >>>
> > >>> I guess it needs another KIP after this KIP gets merged.
> > >>>
> > >>>
> > >>> Best,
> > >>>
> > >>> Chia-Ping
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>
> > >>> Matthias J. Sax <mj...@apache.org> 於 2024年10月1日 週二 上午1:16寫道:
> > >>>
> > >>>> I am also in favor of consistent APIs. That's very good point. I did
> > >>>> not
> > >>>> take `Admin` API into account, and I am not aware that consumer /
> > >>>> producer would have config object classes?
> > >>>>
> > >>>> Seems we are in a tricky situation here, because "consistent API" to
> > me
> > >>>> means producer, consumer, admin and KS.
> > >>>>
> > >>>> The KS surface area might be the largest one (even if there is a
> long
> > >>>> list of `XxxOption` classes for Admin API), and we do follow the
> > >>>> pattern
> > >>>> as described. It's of course not desirable to just change the whole
> > >>>> Admin API (and neither the KS API), but it might be good to agree
> on a
> > >>>> "gold standard" and do everything new accordingly?
> > >>>>
> > >>>> Given that producer / consumer do not have any config object classes
> > >>>> yet, it seems to be the question if they should follow the Admin
> > >>>> pattern
> > >>>> or the KS pattern. -- I tend to think, following the KS pattern
> > >>>> might be
> > >>>> better? But yes, I see your POV to say it should follow the Admin
> API
> > >>>> pattern, however, it would imply that we "need" to change all the KS
> > >>> APIs.
> > >>>>
> > >>>> Overall, the "static method builder" pattern seems better to me, and
> > >>>> thus I would prefer to make it the "gold standard" and we can see
> what
> > >>>> we can do for `Admin API` mid/long term?
> > >>>>
> > >>>>
> > >>>> Let's see what others think.
> > >>>>
> > >>>>
> > >>>> Btw: I was also wondering, if we should re-use the new consumer
> > >>>> `CloseOption` class for `KafkaStreams#close()` and deprecate the KS
> > >>>> `CloseOption` class? Not sure. Just another "random" idea.
> > >>>>
> > >>>>
> > >>>>
> > >>>> -Matthias
> > >>>>
> > >>>>
> > >>>> On 9/29/24 12:08 PM, Chia-Ping Tsai wrote:
> > >>>>>>   From an API POV, I think the new `CloseOptions` class should not
> > >>>>>> have
> > >>>>> any "getters" and thus, it's irrelevant how we represent the
> > different
> > >>>>> cases in code internally (even if I believe using `Optional` might
> > >>>>> be a
> > >>>>> good way to handle it).
> > >>>>>
> > >>>>> If we choose to avoid using getters, consumers would have to access
> > >>>>> the
> > >>>>> internal variables directly, similar to how it's done in the
> streams
> > >>>>> CloseOptions. While this is a matter of preference, it's worth
> noting
> > >>>> that
> > >>>>> Admin options do provide both setters and getters. In my opinion,
> > >>>>> since
> > >>>> all
> > >>>>> of these options are part of the kafka-clients code, they should
> > >>>>> adhere
> > >>>> to
> > >>>>> a consistent coding style.
> > >>>>>
> > >>>>>> In KS, we use config objects like `CloseOption` all the time, with
> > >>>> static
> > >>>>> "factory" method (and private constructors), and an internal
> > >>>>> sub-class
> > >>>>> which would have the getters if needed. So I think we should have
> > >>>>>
> > >>>>> I value the static factory methods for their convenience, allowing
> > >>> users
> > >>>> to
> > >>>>> quickly create an object when they want to set only one option.
> > >>> However,
> > >>>>> while I don't want to sound repetitive, maintaining a consistent
> > >>> pattern
> > >>>>> across the API is essential.
> > >>>>>
> > >>>>> Best,
> > >>>>> Chia-Ping
> > >>>>>
> > >>>>>
> > >>>>> Matthias J. Sax <mj...@apache.org> 於 2024年9月30日 週一 上午2:26寫
> > >>>>> 道:
> > >>>>>
> > >>>>>> I am not sure, but I get the impression that we are starting to
> talk
> > >>> too
> > >>>>>> much about implementation details now?
> > >>>>>>
> > >>>>>>    From an API POV, I think the new `CloseOptions` class should
> not
> > >>> have
> > >>>>>> any "getters" and thus, it's irrelevant how we represent the
> > >>>>>> different
> > >>>>>> cases in code internally (even if I believe using `Optional` might
> > be
> > >>> a
> > >>>>>> good way to handle it).
> > >>>>>>
> > >>>>>> In KS, we use config objects like `CloseOption` all the time, with
> > >>>>>> static "factory" method (and private constructors), and an
> internal
> > >>>>>> sub-class which would have the getters if needed. So I think we
> > >>>>>> should
> > >>>> have
> > >>>>>>
> > >>>>>> public class CloseOptions {
> > >>>>>>        private CloseOptions(Optional<Duration>,
> Optional<boolean>);
> > >>>>>>
> > >>>>>>        public static CloseOptions timeout(Duration);
> > >>>>>>
> > >>>>>>        public static CloseOptions leaveGroup(boolean);
> > >>>>>>
> > >>>>>>        public CloseOption withTimeout(Duration);
> > >>>>>>
> > >>>>>>        public CloseOption withLeaveGroup(boolean);
> > >>>>>> }
> > >>>>>>
> > >>>>>>
> > >>>>>> This allows to call as example:
> > >>>>>>
> > >>>>>>      consumer.close(CloseOptions.leaveGroup(true));
> > >>>>>>
> > >>>>>> or
> > >>>>>>
> > >>>>>>      consumer.close(
> > >>>>>>           CloseOptions.timeout(Duration.ofMinutes(5)
> > >>>>>>                       .withLeaveGroup(false)
> > >>>>>>       );
> > >>>>>>
> > >>>>>> We can still discuss naming and what overloads we want to add, but
> > in
> > >>>>>> general, a well established and proven pattern is to have a few
> > >>>>>> static
> > >>>>>> "entry" methods, with return the object itself to allow chaining
> > with
> > >>>>>> non-static methods.
> > >>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>>> I am not sure, why KIP-812 did not follow this pattern... I think
> it
> > >>> got
> > >>>>>> it wrong and we should not repeat this "mistake". Maybe we could
> > >>>>>> actually piggy-pack a cleanup for the existing KS CloseOption
> object
> > >>>>>> into this KIP?
> > >>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>>> -Matthias
> > >>>>>>
> > >>>>>> On 9/29/24 8:39 AM, TengYao Chi wrote:
> > >>>>>>> Hi Chia-Ping,
> > >>>>>>>
> > >>>>>>> Thanks for your feedback.
> > >>>>>>> What I intended to express is that if `Optional.empty()` is
> > >>>>>>> passed to
> > >>>> the
> > >>>>>>> `timeout`, it will eventually be converted to
> > >>>> `DEFAULT_CLOSE_TIMEOUT_MS`,
> > >>>>>>> just as you mentioned.
> > >>>>>>> Apologies for not expressing that clearly and for any confusion
> > >>> caused.
> > >>>>>>>
> > >>>>>>> Best regards,
> > >>>>>>> TengYao
> > >>>>>>>
> > >>>>>>> Chia-Ping Tsai <chia7...@gmail.com> 於 2024年9月29日 週日 下午
> > >>>>>>> 10:16寫道:
> > >>>>>>>
> > >>>>>>>> hi TengYao
> > >>>>>>>>
> > >>>>>>>>> I have reviewed the `close()` method implementation for both
> the
> > >>>>>> Classic
> > >>>>>>>> and Async Consumers. I believe the `timeout` parameter could
> have
> > a
> > >>>>>> default
> > >>>>>>>> value, and this default should align with the existing
> > >>>>>> `Consumer#close()`
> > >>>>>>>> method, which internally calls the overloaded
> > >>>> `Consumer#close(Duration)`
> > >>>>>>>> with a default of 30 seconds (`DEFAULT_CLOSE_TIMEOUT_MS`).
> > >>>>>>>>
> > >>>>>>>> If you assign a default value (30s) to CloseOptions#timeout, the
> > >>>>>> consumer
> > >>>>>>>> won't be able to differentiate between the "default" and
> > >>>> "user-defined"
> > >>>>>>>> behaviors.
> > >>>>>>>>
> > >>>>>>>> Therefore, I prefer to leave the timeout empty as the default
> > >>>>>>>> value,
> > >>>>>>>> allowing the consumer to handle it in a way that reflects
> default
> > >>>>>> behavior.
> > >>>>>>>> Best,
> > >>>>>>>> Chia-Ping
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>> TengYao Chi <kiting...@gmail.com> 於 2024年9月29日 週日 下午2:23
> > >>>>>>>> 寫道:
> > >>>>>>>>
> > >>>>>>>>> Hi Sophie,
> > >>>>>>>>>
> > >>>>>>>>> Thanks for the suggestions.
> > >>>>>>>>>
> > >>>>>>>>> I have reviewed the `close()` method implementation for both
> the
> > >>>>>> Classic
> > >>>>>>>>> and Async Consumers. I believe the `timeout` parameter could
> > >>>>>>>>> have a
> > >>>>>>>> default
> > >>>>>>>>> value, and this default should align with the existing
> > >>>>>> `Consumer#close()`
> > >>>>>>>>> method, which internally calls the overloaded
> > >>>>>> `Consumer#close(Duration)`
> > >>>>>>>>> with a default of 30 seconds (`DEFAULT_CLOSE_TIMEOUT_MS`).
> > >>>>>>>>>
> > >>>>>>>>> Regarding the `leaveGroup` parameter, since static and dynamic
> > >>>> members
> > >>>>>>>> have
> > >>>>>>>>> different default behaviors upon close, and the primitive type
> > >>>> boolean
> > >>>>>>>>> cannot capture all cases, I agree with Chia-Ping’s suggestion
> of
> > >>>> using
> > >>>>>>>>> Optional instead. This approach avoids potential NPE issues
> that
> > >>>> could
> > >>>>>>>>> arise from using the boxed type Boolean and allows us to cover
> > all
> > >>>> use
> > >>>>>>>>> cases more effectively.
> > >>>>>>>>>
> > >>>>>>>>> Given the above, although there is no standard in the Consumer
> > API
> > >>>> (as
> > >>>>>>>> far
> > >>>>>>>>> as I know), I believe adopting a fluent API would be
> > >>>>>>>>> beneficial, as
> > >>>> it
> > >>>>>>>>> would be more user-friendly and concise for configuring the
> > >>> necessary
> > >>>>>>>>> options.
> > >>>>>>>>>
> > >>>>>>>>> Best,
> > >>>>>>>>> TengYao
> > >>>>>>>>>
> > >>>>>>>>> Chia-Ping Tsai <chia7...@gmail.com> 於 2024年9月29日 週日 上午
> > >>>>>>>>> 7:07寫道:
> > >>>>>>>>>
> > >>>>>>>>>> hi Sophie
> > >>>>>>>>>>
> > >>>>>>>>>> Fewer overloads are preferable, so in my opinion, the consumer
> > >>>> should
> > >>>>>>>>> only
> > >>>>>>>>>> have close() and close(CloseOptions), with the other overloads
> > >>>>>>>>> deprecated.
> > >>>>>>>>>>
> > >>>>>>>>>> That means all options in CloseOptions should be optional, and
> > we
> > >>>>>>>> should
> > >>>>>>>>>> use a fluent-style API to add setters for them. This would
> allow
> > >>>> users
> > >>>>>>>> to
> > >>>>>>>>>> configure only the necessary options while leaving the rest at
> > >>> their
> > >>>>>>>>>> default values. For example:
> > >>>>>>>>>>
> > >>>>>>>>>> // case 0: set both timeout and leaveGroup
> > >>>>>>>>>> new CloseOptions()
> > >>>>>>>>>>      .timeout(100)
> > >>>>>>>>>>      .leaveGroup(false);
> > >>>>>>>>>>
> > >>>>>>>>>> // case 1: set only timeout and leaveGroup is default
> > >>>>>>>>>> new CloseOptions()
> > >>>>>>>>>>      .timeout(100)
> > >>>>>>>>>>
> > >>>>>>>>>> // case 2: set only leaveGroup, and timeout is default
> > >>>>>>>>>> new CloseOptions()
> > >>>>>>>>>>      .leaveGroup(true)
> > >>>>>>>>>>
> > >>>>>>>>>> Additionally, all getters of CloseOptions return Optional<>,
> > >>>>>>>>>> which
> > >>>> can
> > >>>>>>>>>> distinguish between a "default" value and a "user-defined"
> > value.
> > >>>> For
> > >>>>>>>>>> another, `close()` can have default implementation by
> `close(new
> > >>>>>>>>>> CloseOptions())`
> > >>>>>>>>>>
> > >>>>>>>>>> Best,
> > >>>>>>>>>> Chia-Ping
> > >>>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>> Sophie Blee-Goldman <sop...@responsive.dev> 於 2024年9月29日 週日
> > >>>> 上午5:52寫道:
> > >>>>>>>>>>
> > >>>>>>>>>>> @Matthias, regarding your questions in 101, is it fair to
> > >>> summarize
> > >>>>>>>>> your
> > >>>>>>>>>>> points here as (A) only Kafka Streams, but not plain
> consumer,
> > >>>> would
> > >>>>>>>>> need
> > >>>>>>>>>>> to avoid leaving the group on close (for non-static members),
> > >>>>>>>>>>> and
> > >>>> (B)
> > >>>>>>>>>> with
> > >>>>>>>>>>> KIP-1088 we will soon have a Streams-specific Consumer API
> that
> > >>>> would
> > >>>>>>>>> be
> > >>>>>>>>>>> more suited to these kinds of Streams-specific APIs, and
> > >>> therefore
> > >>>>>>>> -->
> > >>>>>>>>>> (C)
> > >>>>>>>>>>> it doesn't make sense to do this KIP now and we should just
> > wait
> > >>>> for
> > >>>>>>>>> 1088
> > >>>>>>>>>>> so we can apply the API on top of it?
> > >>>>>>>>>>>
> > >>>>>>>>>>> If that's a fair summary, then I would have to disagree. Not
> > >>>> sending
> > >>>>>>>> a
> > >>>>>>>>>>> LeaveGroup on close for dynamic members isn't some highly
> > >>>>>>>>>>> specific optimization that could only ever make sense in the
> > >>>> context
> > >>>>>>>> of
> > >>>>>>>>>>> Kafka Streams. IT doesn't really have to do with Kafka
> > >>>>>>>>>>> Streams at
> > >>>>>>>> all,
> > >>>>>>>>>> it's
> > >>>>>>>>>>> just a good thing to do for stateful apps where you don't
> > >>>>>>>>>>> want to
> > >>>>>>>>> shuffle
> > >>>>>>>>>>> around partitions too much after a simple bounce. So imo this
> > >>>>>>>>>>> KIP
> > >>>>>>>> makes
> > >>>>>>>>>>> sense to do as-is, and people have been asking for it for
> quite
> > >>>> some
> > >>>>>>>>> time
> > >>>>>>>>>>> so I wouldn't want to delay this any further if possible.
> > >>>>>>>>>>>
> > >>>>>>>>>>> Also, this is technically a bit of an implementation detail
> so
> > >>>>>>>> perhaps
> > >>>>>>>>> it
> > >>>>>>>>>>> doesn't belong in the KIP, but I think we should remove the
> > >>>>>>>>>>> "internal.leave.group.pon.close" ConsumerConfig that was used
> > >>>>>>>>> exclusively
> > >>>>>>>>>>> by Kafka Streams since we can now use the new
> > >>>>>>>>>> Consumer#close(CloseOptions)
> > >>>>>>>>>>> API for everything. And we should mention doing this in the
> > KIP,
> > >>>> even
> > >>>>>>>>>>> though it's an internal config, just in case someone out
> > >>>>>>>>>>> there is
> > >>>>>>>> using
> > >>>>>>>>>> it.
> > >>>>>>>>>>>
> > >>>>>>>>>>> @Chia-Ping
> > >>>>>>>>>>> Regarding what the default behavior, I think it probably
> makes
> > >>>> sense
> > >>>>>>>> to
> > >>>>>>>>>>> leave the default behavior of the CloseOptions identical to
> the
> > >>>>>>>>> existing
> > >>>>>>>>>>> Consumer#close overloads to avoid making things too
> complicated
> > >>> for
> > >>>>>>>>> users
> > >>>>>>>>>>> to understand. Especially if we're not going to remove the
> old
> > >>>> #close
> > >>>>>>>>>>> overloads
> > >>>>>>>>>>>
> > >>>>>>>>>>> @TengYao
> > >>>>>>>>>>> Thanks for adding the specific APIs. We should probably first
> > >>>>>>>> determine
> > >>>>>>>>>>> things like which parameters of CloseOptions should be
> required
> > >>> and
> > >>>>>>>>> which
> > >>>>>>>>>>> can be left to the default (plus what that default is: see
> > above
> > >>>>>>>>>>> conversation with Chia-Ping) and then we can design the API
> > >>> around
> > >>>>>>>>> that.
> > >>>>>>>>>> I
> > >>>>>>>>>>> noticed for example that with the current proposal, it would
> be
> > >>>>>>>>>> impossible
> > >>>>>>>>>>> to set both the leaveGroup and timeOut parameters of the
> > >>>>>>>> CloseOptions.
> > >>>>>>>>> We
> > >>>>>>>>>>> need to make sure the available public constructors allow
> users
> > >>> to
> > >>>>>>>> set
> > >>>>>>>>>> the
> > >>>>>>>>>>> full range of configs. We could also use a fluent-style API
> > like
> > >>> we
> > >>>>>>>> do
> > >>>>>>>>> in
> > >>>>>>>>>>> Kafka Streams for config objects. Not sure what (if anything)
> > is
> > >>>> the
> > >>>>>>>>>>> standard for Consumer APIs?
> > >>>>>>>>>>>
> > >>>>>>>>>>>
> > >>>>>>>>>>> Finally, one open-ended question I have for everyone here:
> > >>>>>>>>>>> should
> > >>>> the
> > >>>>>>>>>>> leaveGroup config be a required parameter of CloseOptions? Or
> > >>>> should
> > >>>>>>>> we
> > >>>>>>>>>>> allow users to pass in an "empty" CloseOptions to leave both
> > the
> > >>>>>>>>> timeout
> > >>>>>>>>>>> and leaveGroup behavior to the default?
> > >>>>>>>>>>>
> > >>>>>>>>>>>
> > >>>>>>>>>>>
> > >>>>>>>>>>> On Sat, Sep 28, 2024 at 9:58 AM Chia-Ping Tsai <
> > >>> chia7...@gmail.com
> > >>>>>
> > >>>>>>>>>> wrote:
> > >>>>>>>>>>>
> > >>>>>>>>>>>> hi TengYao
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> Could you please consider adding a "default" behavior for
> > >>>>>>>> leaveGroup?
> > >>>>>>>>>> As
> > >>>>>>>>>>> I
> > >>>>>>>>>>>> previously mentioned, leaveGroup=true is not ideal as the
> > >>> default
> > >>>>>>>> for
> > >>>>>>>>>>>> static members, and similarly, leaveGroup=false is not
> > suitable
> > >>> as
> > >>>>>>>>> the
> > >>>>>>>>>>>> default for dynamic members.
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> Maybe we could change the type of leaveGroup to
> > >>> Optional<Boolean>,
> > >>>>>>>>>>> allowing
> > >>>>>>>>>>>> it to represent three distinct behaviors.
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> Best,
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> Chia-Ping
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> TengYao Chi <kiting...@gmail.com> 於 2024年9月29日 週日 上午
> > >>>>>>>>>>>> 12:51寫道:
> > >>>>>>>>>>>>
> > >>>>>>>>>>>>> Hi Sophie
> > >>>>>>>>>>>>>
> > >>>>>>>>>>>>> Thanks for feedback.
> > >>>>>>>>>>>>> I have updated the Public Interface part accordingly.
> > >>>>>>>>>>>>> Please take a look.
> > >>>>>>>>>>>>>
> > >>>>>>>>>>>>> Best,
> > >>>>>>>>>>>>> TengYao
> > >>>>>>>>>>>>>
> > >>>>>>>>>>>>> TengYao Chi <kiting...@gmail.com> 於 2024年9月28日 週六 下
> > >>>>>>>>>>>>> 午1:26寫道:
> > >>>>>>>>>>>>>
> > >>>>>>>>>>>>>> Hi Matthias,
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> Thanks for the explanation, particularly regarding the
> > >>>>>>>> important
> > >>>>>>>>>>>>>> considerations for both the plain consumer and Kafka
> Streams
> > >>>>>>>> use
> > >>>>>>>>>>> cases.
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> In this case, I think it would be better to stick with my
> > >>>>>>>> initial
> > >>>>>>>>>>>>>> proposal. We should give plain consumers the ability to
> > >>>>>>>> determine
> > >>>>>>>>>>>> whether
> > >>>>>>>>>>>>>> to send a leave group request or not, with clear
> > >>>>>>>>>>>>>> documentation
> > >>>>>>>>>>>>> highlighting
> > >>>>>>>>>>>>>> the potential downsides. This could also provide
> flexibility
> > >>>>>>>> for
> > >>>>>>>>>>> future
> > >>>>>>>>>>>>>> features.
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> Best,
> > >>>>>>>>>>>>>> TengYao
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>> Chia-Ping Tsai <chia7...@gmail.com> 於 2024年9月28日 週六
> > >>>>>>>>>>>>>> 上午3:27寫道:
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>> hi Matthias
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>     100: Why do we want to distinguish between the
> classic
> > >>> and
> > >>>>>>>>> the
> > >>>>>>>>>>> new
> > >>>>>>>>>>>>>>> async
> > >>>>>>>>>>>>>>> consumer? Should they not have the same (user facing)
> > >>>>>>>> behavior?
> > >>>>>>>>> Or
> > >>>>>>>>>>>> maybe
> > >>>>>>>>>>>>>>> I misunderstand something. Can one catch we up what epoch
> > >>> "-1"
> > >>>>>>>>> vs
> > >>>>>>>>>>>> epoch
> > >>>>>>>>>>>>>>> "-2" means?
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>> I apologize for any confusion in my earlier explanation.
> > The
> > >>>>>>>>> way a
> > >>>>>>>>>>>>>>> consumer
> > >>>>>>>>>>>>>>> leaves a group varies between the Classic Consumer and
> the
> > >>>>>>>> Async
> > >>>>>>>>>>>>> Consumer:
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>> - The *Classic Consumer* uses a LeaveGroupRequest but
> does
> > >>>>>>>> *not*
> > >>>>>>>>>>> send
> > >>>>>>>>>>>>> this
> > >>>>>>>>>>>>>>> request for static members.
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>> - In contrast, the *Async Consumer* sends a
> > >>>>>>>>>>>>> ConsumerGroupHeartbeatRequest.
> > >>>>>>>>>>>>>>> If the member is static, this request is sent with an
> epoch
> > >>>>>>>>> value
> > >>>>>>>>>> of
> > >>>>>>>>>>>> -2,
> > >>>>>>>>>>>>>>> indicating that the static member has temporarily left
> the
> > >>>>>>>> group
> > >>>>>>>>>> and
> > >>>>>>>>>>>> is
> > >>>>>>>>>>>>>>> *not* removed. An epoch of -1 in the CONSUMER protocol
> > >>>>>>>> signifies
> > >>>>>>>>>>> that
> > >>>>>>>>>>>>> the
> > >>>>>>>>>>>>>>> static member is treated as a dynamic member and will
> leave
> > >>>>>>>> the
> > >>>>>>>>>>> group
> > >>>>>>>>>>>>>>> completely.
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>> Hence, even if not useful for the plain consumer to
> > disable
> > >>>>>>>>>>> sending
> > >>>>>>>>>>>> a
> > >>>>>>>>>>>>>>> leave-group-request, it might be worth to add a generic
> > >>>>>>>>>>> enable/disable
> > >>>>>>>>>>>>>>> API
> > >>>>>>>>>>>>>>> for both dynamic and static groups, so KS can use this
> API
> > >>>>>>>> (and
> > >>>>>>>>> we
> > >>>>>>>>>>>>> could
> > >>>>>>>>>>>>>>> remove the internal consumer config, which is a
> workaround
> > >>>>>>>>>> anyway).
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>> I agree that having a generic enable/disable API would be
> > >>>>>>>>>>> beneficial,
> > >>>>>>>>>>>>>>> especially if we can provide comprehensive documentation.
> > >>> This
> > >>>>>>>>>>>>>>> documentation should clearly outline the potential
> > downsides
> > >>>>>>>> of
> > >>>>>>>>>> not
> > >>>>>>>>>>>>>>> sending
> > >>>>>>>>>>>>>>> a LEAVE_REQUEST for dynamic members, ensuring users are
> > >>>>>>>>>>> well-informed
> > >>>>>>>>>>>>>>> about
> > >>>>>>>>>>>>>>> the implications of their choices.
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>> Best,
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>> Chia-Ping
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>> Matthias J. Sax <mj...@apache.org> 於 2024年9月28日 週六
> > >>>>>>>>>>>>>>> 上午2:07寫道:
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>> Thanks for the KIP. Two questions/comments:
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>> 100: Why do we want to distinguish between the classic
> and
> > >>>>>>>> the
> > >>>>>>>>>> new
> > >>>>>>>>>>>>> async
> > >>>>>>>>>>>>>>>> consumer? Should they not have the same (user facing)
> > >>>>>>>>> behavior?
> > >>>>>>>>>> Or
> > >>>>>>>>>>>>> maybe
> > >>>>>>>>>>>>>>>> I misunderstand something. Can one catch we up what
> epoch
> > >>>>>>>> "-1"
> > >>>>>>>>>> vs
> > >>>>>>>>>>>>> epoch
> > >>>>>>>>>>>>>>>> "-2" means?
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>> 101: I think we need to distinguish between the plain
> > >>>>>>>> consumer
> > >>>>>>>>>> and
> > >>>>>>>>>>>> the
> > >>>>>>>>>>>>>>>> KS case.
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>> Plain consumer: for this case, atm user don't have
> control
> > >>>>>>>> at
> > >>>>>>>>>> all,
> > >>>>>>>>>>>> but
> > >>>>>>>>>>>>>>>> it's hard coded when a leave group request is sent. If
> we
> > >>>>>>>> only
> > >>>>>>>>>>>>> consider
> > >>>>>>>>>>>>>>>> this case, the current KIP to allow sending a
> leave-group
> > >>>>>>>>>> request
> > >>>>>>>>>>>> for
> > >>>>>>>>>>>>>>>> static members is sufficient. I agree that disabling
> > >>>>>>>>> leave-group
> > >>>>>>>>>>>>> request
> > >>>>>>>>>>>>>>>> for dynamic member is not necessary for the plain
> consumer
> > >>>>>>>>> case.
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>> However, for the KS case it's different. Because KS uses
> > >>>>>>>>>>>>>>>> the
> > >>>>>>>>>>>> internal
> > >>>>>>>>>>>>>>>> config to disable sending leave group request for
> dynamic
> > >>>>>>>>>> members,
> > >>>>>>>>>>>> we
> > >>>>>>>>>>>>>>>> lack an user facing API to enable sending a leave group
> > >>>>>>>>> request
> > >>>>>>>>>>> for
> > >>>>>>>>>>>>> this
> > >>>>>>>>>>>>>>>> case, and if we only allow to enable sending leave group
> > >>>>>>>>> request
> > >>>>>>>>>>> for
> > >>>>>>>>>>>>>>>> static members on the consumer, the KIP would fall short
> > to
> > >>>>>>>>>> close
> > >>>>>>>>>>>> this
> > >>>>>>>>>>>>>>> gap.
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>> Hence, even if not useful for the plain consumer to
> > disable
> > >>>>>>>>>>> sending
> > >>>>>>>>>>>> a
> > >>>>>>>>>>>>>>>> leave-group-request, it might be worth to add a generic
> > >>>>>>>>>>>> enable/disable
> > >>>>>>>>>>>>>>>> API for both dynamic and static groups, so KS can use
> this
> > >>>>>>>> API
> > >>>>>>>>>>> (and
> > >>>>>>>>>>>> we
> > >>>>>>>>>>>>>>>> could remove the internal consumer config, which is a
> > >>>>>>>>> workaround
> > >>>>>>>>>>>>>>> anyway).
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>> On the other hand, given the light of KIP-1088, maybe
> > there
> > >>>>>>>>> are
> > >>>>>>>>>>>> other
> > >>>>>>>>>>>>>>>> ways to fix it on the KS side? I think the goal should
> > >>>>>>>>>>>>>>>> be to
> > >>>>>>>>>>> remove
> > >>>>>>>>>>>>> the
> > >>>>>>>>>>>>>>>> internal consumer config (as it's static, and we cannot
> > >>>>>>>>>> overwrite
> > >>>>>>>>>>> it
> > >>>>>>>>>>>>> at
> > >>>>>>>>>>>>>>>> runtime), and to give KS a way to dynamically send a
> > >>>>>>>>>>>>> leave-group-request
> > >>>>>>>>>>>>>>>> on close() -- but maybe we could build this on an
> internal
> > >>>>>>>>>>> consumer
> > >>>>>>>>>>>>> API,
> > >>>>>>>>>>>>>>>> and not make it public? For this case, the current KIP
> > >>>>>>>>>>>>>>>> would
> > >>>>>>>>> be
> > >>>>>>>>>>>>>>> sufficient.
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>> -Matthias
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>> On 9/26/24 8:19 PM, Sophie Blee-Goldman wrote:
> > >>>>>>>>>>>>>>>>> Thanks for the KIP! Quick request for readability, can
> > you
> > >>>>>>>>>>> please
> > >>>>>>>>>>>>>>> include
> > >>>>>>>>>>>>>>>>> the exact APIs that you're proposing to add or change
> > >>>>>>>> under
> > >>>>>>>>>> the
> > >>>>>>>>>>>>>>> "Public
> > >>>>>>>>>>>>>>>>> Interfaces" section? The KIP should display the actual
> > >>>>>>>>> method
> > >>>>>>>>>>>>>>> signature
> > >>>>>>>>>>>>>>>> and
> > >>>>>>>>>>>>>>>>> any applicable javadocs for new public APIs.
> > >>>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>> You can look at other KIPs for a clear sense of what it
> > >>>>>>>>> should
> > >>>>>>>>>>>>>>> contain,
> > >>>>>>>>>>>>>>>> but
> > >>>>>>>>>>>>>>>>> here's one example you could work from:
> > >>>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>
> > >>>>>>>>>>>>
> > >>>>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>
> > >>>>>>>>
> > >>>>>>
> > >>>>
> > >>>
> >
> https://cwiki.apache.org/confluence/display/KAFKA/KIP-1036%3A+Extend+RecordDeserializationException+exception
> > >>>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>> On Thu, Sep 26, 2024 at 6:22 PM Chia-Ping Tsai <
> > >>>>>>>>>>>> chia7...@gmail.com>
> > >>>>>>>>>>>>>>>> wrote:
> > >>>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>>>> I think I’m actually OK with leaving it as leaveGroup
> > >>>>>>>>> with a
> > >>>>>>>>>>> lot
> > >>>>>>>>>>>>> of
> > >>>>>>>>>>>>>>>>>> documentation that warns users away from changing it
> > >>>>>>>>>>> arbitrarily.
> > >>>>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>>> Pardon me, I just want to ensure we are all on the
> same
> > >>>>>>>>> page.
> > >>>>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>>>        1. `leaveGroup=true`:  `ClassicKafkaConsumer`
> > >>>>>>>>>>>>>>>>>> sends
> > >>> a
> > >>>>>>>>>>>>>>>>>>        `LeaveGroupRequest` for either the dynamic or
> > >>>>>>>>>>>>>>>>>> static
> > >>>>>>>>>>> member.
> > >>>>>>>>>>>>>>>>>>        2. `leaveGroup=false`:  `ClassicKafkaConsumer`
> > >>>>>>>>>>>>>>>>>> does
> > >>>>>>>> not
> > >>>>>>>>>>> send
> > >>>>>>>>>>>>> any
> > >>>>>>>>>>>>>>> `
> > >>>>>>>>>>>>>>>>>>        LeaveGroupRequest` for either the dynamic or
> > >>>>>>>>>>>>>>>>>> static
> > >>>>>>>>>> member.
> > >>>>>>>>>>>>>>>>>>        3. `leaveGroup=default` (current behavior):
> > >>>>>>>>>>>>>>> `ClassicKafkaConsumer`
> > >>>>>>>>>>>>>>>> sends
> > >>>>>>>>>>>>>>>>>>        a `LeaveGroupRequest` for dynamic member, and
> it
> > >>> does
> > >>>>>>>>> NOT
> > >>>>>>>>>>>> send
> > >>>>>>>>>>>>>>> any
> > >>>>>>>>>>>>>>>>>>        `ConsumerGroupHeartbeatRequest`for static
> member
> > >>>>>>>>>>>>>>>>>>        4. `leaveGroup=true`:  `AsyncKafkaConsumer`
> > >>>>>>>>>>>>>>>>>> sends a
> > >>>>>>>>>>>>>>>>>>        `ConsumerGroupHeartbeatRequest` with "-1" epoch
> > >>>>>>>>>>>>>>>>>> for
> > >>>>>>>>>> either
> > >>>>>>>>>>>> the
> > >>>>>>>>>>>>>>>> dynamic
> > >>>>>>>>>>>>>>>>>> or
> > >>>>>>>>>>>>>>>>>>        static member
> > >>>>>>>>>>>>>>>>>>        5. `leaveGroup=false`: `AsyncKafkaConsumer`
> > >>>>>>>>>>>>>>>>>> sends a
> > >>>>>>>>>>>>>>>>>>        `ConsumerGroupHeartbeatRequest` with "-2" epoch
> > >>>>>>>>>>>>>>>>>> for
> > >>>>>>>> the
> > >>>>>>>>>>>> static
> > >>>>>>>>>>>>>>>> member,
> > >>>>>>>>>>>>>>>>>> and
> > >>>>>>>>>>>>>>>>>>        it does NOT send any
> > >>>>>>>>>>>>>>>>>> `ConsumerGroupHeartbeatRequest`
> > >>>>>>>>> for
> > >>>>>>>>>>>>> dynamic
> > >>>>>>>>>>>>>>>> member
> > >>>>>>>>>>>>>>>>>>        6. `leaveGroup=default` (current behavior):
> > >>>>>>>>>>>>> `AsyncKafkaConsumer`
> > >>>>>>>>>>>>>>>> sends a
> > >>>>>>>>>>>>>>>>>>        `ConsumerGroupHeartbeatRequest`with "-1" epoch
> > for
> > >>>>>>>>>> dynamic
> > >>>>>>>>>>>>> member
> > >>>>>>>>>>>>>>>> and
> > >>>>>>>>>>>>>>>>>>        "-2" epoch for static member
> > >>>>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>>> Best,
> > >>>>>>>>>>>>>>>>>> Chia-Ping
> > >>>>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>>
> > >>>>>>>>>>>>>>
> > >>>>>>>>>>>>>
> > >>>>>>>>>>>>
> > >>>>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>
> > >>>>>>>>
> > >>>>>>>
> > >>>>>>
> > >>>>>
> > >>>>
> > >>>
> > >>
> >
>

Reply via email to