hi Jiunn-Yang

chia05:

`task.assigned.groups` and `task.assigned.partitions` should not have
default value, right?

chia06:

`new HashSet<>(values).size()` -> `Set.copyOf(values).size()`

Best,
Chia-Ping

Jun Rao <j...@confluent.io.invalid> 於 2025年8月5日 週二 下午11:39寫道:

> Hi, Jiunn-Yang,
>
> Thanks for the reply and your patience. The KIP looks good to me now.
>
> Hi, Luke, Mickael,
>
> Could you take a look at the KIP again and see if it makes sense to you?
>
> Thanks,
>
> Jun
>
> On Tue, Aug 5, 2025 at 3:04 AM 黃竣陽 <s7133...@gmail.com> wrote:
>
> > Hello Jun,
> >
> > Thanks for the reply,
> >
> > JR46: I have clarified the behavior for null and empty values, so users
> > can
> > understand the reasoning behind disallowing empty lists.
> >
> > JR48: I've updated the KIP accordingly.
> >
> > Best Regards,
> > Jiunn-Yang
> >
> > > Jun Rao <j...@confluent.io.INVALID> 於 2025年8月5日 凌晨12:45 寫道:
> > >
> > > Hi, Jiunn-Yang,
> > >
> > > Thanks for the reply.
> > >
> > > JR46. "Currently, if plugin.path is set to an empty list, no
> > user-specified
> > > plugin locations are processed, but plugins from the parent classloader
> > are
> > > still loaded." Could you add why the current behavior is bad for the
> > users?
> > >
> > > JR48. If we want to preserve the current behavior, we should remove the
> > > following validation, right?
> > >        if (validStrings.length == 0) {
> > >            throw new IllegalArgumentException("Valid strings list
> cannot
> > > be empty for in validator");
> > >
> > > Jun
> > >
> > > On Fri, Aug 1, 2025 at 6:47 PM 黃竣陽 <s7133...@gmail.com> wrote:
> > >
> > >> Hello Jun,
> > >>
> > >> Thanks for the reply.
> > >>
> > >> JR42, JR45, JR46, JR47: I have updated the KIP.
> > >>
> > >> JR43: If bootstrap.servers is empty for these configurations,
> > >> it will fail when creating the AdminClient. I have updated the KIP to
> > >> reflect this behavior.
> > >>
> > >> JR44: Thanks for pointing this out. Kafka will indeed fail at the
> > storage
> > >> format phase
> > >> if the configuration is invalid. I have updated the KIP accordingly.
> > >>
> > >> JR48: The current in() method allows empty lists by default, so I
> > believe
> > >> setting isEmptyAllowed to true
> > >> better preserves the original behavior. Therefore, I prefer not to
> > change
> > >> this default.
> > >>
> > >> Best Regards,
> > >> Jiunn-Yang
> > >>
> > >>> Jun Rao <j...@confluent.io.INVALID> 於 2025年8月2日 凌晨2:38 寫道:
> > >>>
> > >>> Hi, Jiunn-Yang,
> > >>>
> > >>> Thanks for the reply. A few more comments.
> > >>>
> > >>> JR42. [6] [7] are not needed since currently an empty list already
> > causes
> > >>> an exception.
> > >>>
> > >>> JR43. Could you document the current behavior when bootstrap.servers
> is
> > >>> empty in MirrorClientConfig and WorkerConfig?
> > >>>
> > >>> JR44. [12] seems incorrect. I set log.dir, but left log.dirs empty
> and
> > >> got
> > >>> the following.
> > >>> bin/kafka-storage.sh format --standalone -t $KAFKA_CLUSTER_ID -c
> > >>> config/server.properties
> > >>> Exception in thread "main" java.lang.IllegalArgumentException:
> > >> requirement
> > >>> failed: At least one log directory must be defined via log.dirs or
> > >> log.dir.
> > >>>
> > >>> bin/kafka-server-start.sh config/server.properties
> > >>> [2025-08-01 11:31:20,097] INFO Registered
> > >>> `kafka:type=kafka.Log4jController` MBean
> > >>> (kafka.utils.Log4jControllerRegistration$)
> > >>> [2025-08-01 11:31:20,238] ERROR Exiting Kafka due to fatal exception
> > >>> (kafka.Kafka$)
> > >>> java.lang.IllegalArgumentException: requirement failed: At least one
> > log
> > >>> directory must be defined via log.dirs or log.dir.
> > >>>
> > >>> JR45. Could you group all configs for WorkerConfig together?
> > >>>
> > >>> JR46. plugin.path: We have the following code. So, currently, it
> seems
> > >> that
> > >>> an empty list is allowed for plugin.path and we treat it by adding
> the
> > >>> parent path of the classloader. It would be useful to justify why
> > >>> disallowing empty is better for the users.
> > >>>
> > >>>   public static Set<PluginSource> pluginSources(Set<Path>
> > >>> pluginLocations, ClassLoader classLoader, PluginClassLoaderFactory
> > >> factory)
> > >>> {
> > >>>       Set<PluginSource> pluginSources = new LinkedHashSet<>();
> > >>>       for (Path pluginLocation : pluginLocations) {
> > >>>           try {
> > >>>               pluginSources.add(isolatedPluginSource(pluginLocation,
> > >>> classLoader, factory));
> > >>>           } catch (InvalidPathException | MalformedURLException e) {
> > >>>               log.error("Invalid path in plugin path: {}. Ignoring.",
> > >>> pluginLocation, e);
> > >>>           } catch (IOException e) {
> > >>>               log.error("Could not get listing for plugin path: {}.
> > >>> Ignoring.", pluginLocation, e);
> > >>>           }
> > >>>       }
> > >>>
> >  pluginSources.add(classpathPluginSource(classLoader.getParent()));
> > >>>       return pluginSources;
> > >>>   }
> > >>>
> > >>> JR47. typo in "Should not allow setting validStrings is empty"
> > >>>
> > >>> JR48. We should pass in isEmptyAllowed as false in the code below,
> > right?
> > >>>   public static ValidList in(String... validStrings) {
> > >>>       if (validStrings.length == 0) {
> > >>>           throw new IllegalArgumentException("Valid strings list
> cannot
> > >>> be empty for in validator");
> > >>>       }
> > >>>       return new ValidList(List.of(validStrings), true, false);
> > >>>   }
> > >>>
> > >>> Jun
> > >>>
> > >>> On Tue, Jul 29, 2025 at 8:53 AM 黃竣陽 <s7133...@gmail.com> wrote:
> > >>>
> > >>>> Hello Jun,
> > >>>>
> > >>>> Sorry for the late reply,
> > >>>>
> > >>>> JR40, JR41: I have updated the KIP based on your comments. Please
> > take a
> > >>>> look.
> > >>>>
> > >>>> Best Regards,
> > >>>> Jiunn-Yang
> > >>>>
> > >>>>> Jun Rao <j...@confluent.io.INVALID> 於 2025年7月24日 凌晨2:56 寫道:
> > >>>>>
> > >>>>> Hi, Jiunn-Yang,
> > >>>>>
> > >>>>> Thanks for the reply.
> > >>>>>
> > >>>>> JR40. In the table, there are a few configs for which we now
> disallow
> > >>>> empty
> > >>>>> lists. It would be useful to document the current behavior for each
> > of
> > >>>> them
> > >>>>> more accurately. It seems that they should all lead to some bad
> > >> behavior.
> > >>>>> For example, if log.dirs is empty, it seems that we can't create
> > >> topics?
> > >>>>> If group.coordinator.rebalance.protocols is empty, the group
> > rebalance
> > >>>>> protocol will fail?
> > >>>>>
> > >>>>> JR41. It would be useful to clean up the "Compatibility,
> Deprecation,
> > >> and
> > >>>>> Migration Plan" section a bit.
> > >>>>> JR41.1 The migration plan has "Introduce a new properties
> > >> isEmptyAllowed
> > >>>> ,
> > >>>>> isNullAllowed", which needs to be changed.
> > >>>>> JR41.2 It started with "For users who configure an empty list", but
> > not
> > >>>> all
> > >>>>> the bullet points are about empty lists.
> > >>>>> JR41.3 To me, it would be useful to summarize why the behavior
> > changes
> > >>>> are
> > >>>>> justified. We made 3 types of changes. (1) Disallow null. This is
> ok
> > >>>> since
> > >>>>> one can't really set a null value through a config file. (2)
> Disallow
> > >>>>> duplicates. This is ok since it's rare and confusing. (3) Disallow
> > >> empty.
> > >>>>> Ideally, we want to claim that for those cases, they all lead to
> some
> > >>>> other
> > >>>>> errors or had behavior currently.
> > >>>>>
> > >>>>> Jun
> > >>>>>
> > >>>>> On Wed, Jul 23, 2025 at 4:42 AM 黃竣陽 <s7133...@gmail.com> wrote:
> > >>>>>
> > >>>>>> Hello Jun,
> > >>>>>>
> > >>>>>> Thanks for the reply.
> > >>>>>>
> > >>>>>> JR34 ,JR36, JR39: I’ve updated the KIP to reflect these changes.
> > >>>>>>
> > >>>>>> JR38: I clarified the following configurations:
> > >>>>>> early.start.listeners: This config is optional and allows both
> null
> > >> and
> > >>>>>> empty lists.
> > >>>>>> log.dirs and plugin.path: These are also optional, but only allow
> > >>>>>> null—empty lists are not permitted.
> > >>>>>>
> > >>>>>> Best Regards,
> > >>>>>> Jiunn-Yang
> > >>>>>>
> > >>>>>>> Jun Rao <j...@confluent.io.INVALID> 於 2025年7月23日 凌晨2:28 寫道:
> > >>>>>>>
> > >>>>>>> Hi, Jiunn-Yang and Chia-Ping,
> > >>>>>>>
> > >>>>>>> Thanks for the reply.
> > >>>>>>>
> > >>>>>>> JR34. Sounds good.
> > >>>>>>>
> > >>>>>>> JR36. Could you document that the default value for
> > >>>>>>> sasl.oauthbearer.expected.audience and ssl.cipher.suites have
> been
> > >>>>>> changed?
> > >>>>>>>
> > >>>>>>> JR38. My concern wasn't quite addressed. "If the configuration is
> > >>>>>> optional,
> > >>>>>>> we will reject any duplicate values in the list." This implies
> that
> > >> if
> > >>>> a
> > >>>>>>> config is optional, we allow empty lists. However, for
> plugin.path,
> > >> we
> > >>>>>>> reject empty lists.
> > >>>>>>>
> > >>>>>>> JR39. We can remove the fields isEmptyAllowed and isNullAllowed
> > since
> > >>>>>> they
> > >>>>>>> are not public facing.
> > >>>>>>>
> > >>>>>>> Jun
> > >>>>>>>
> > >>>>>>>
> > >>>>>>> On Tue, Jul 22, 2025 at 4:26 AM 黃竣陽 <s7133...@gmail.com> wrote:
> > >>>>>>>
> > >>>>>>>> Hello Jun, Chia,
> > >>>>>>>>
> > >>>>>>>> Thanks for the reply,
> > >>>>>>>>
> > >>>>>>>> JR36: I’ve updated the following configurations:
> > >>>>>>>> - sasl.oauthbearer.expected.audience
> > >>>>>>>> - ssl.cipher.suites
> > >>>>>>>> - ssl.enabled.protocols
> > >>>>>>>> These now allow both empty and non-empty lists. Since the
> default
> > >>>> values
> > >>>>>>>> of
> > >>>>>>>> sasl.oauthbearer.expected.audience and ssl.cipher.suites were
> > >>>> previously
> > >>>>>>>> null,
> > >>>>>>>> I’ve updated their defaults to List.of() for consistency.
> > >>>>>>>>
> > >>>>>>>> JR37: A ClassCastException does not occur in MirrorClientConfig
> > and
> > >> it
> > >>>>>>>> should be none.
> > >>>>>>>> I’ve updated this in the KIP.
> > >>>>>>>>
> > >>>>>>>> JR38 & JR40: I’ve added a note below the table to indicate which
> > >>>>>>>> configurations require special attention.
> > >>>>>>>>
> > >>>>>>>> JR39: Yes, these properties are package-private.
> > >>>>>>>>
> > >>>>>>>> Best Regards,
> > >>>>>>>> Jiunn-Yang
> > >>>>>>>>
> > >>>>>>>>> Chia-Ping Tsai <chia7...@gmail.com> 於 2025年7月22日 下午6:04 寫道:
> > >>>>>>>>>
> > >>>>>>>>> JR34. Hmm, it seems that the code in taskConfigs() could return
> > an
> > >>>>>> empty
> > >>>>>>>>> list for a task if knownSourceTopicPartitions is less than
> > >> maxTasks,
> > >>>>>>>>> Chia-Ping?
> > >>>>>>>>>
> > >>>>>>>>>
> > >>>>>>>>> Yes, `MirrorSourceConnector#taskConfigs` could return an empty
> > >> list,
> > >>>>>>>> which
> > >>>>>>>>> means no `MirrorSourceTask` can be created.
> > >>>>>>>>>
> > >>>>>>>>> By contrast, if any `MirrorSourceTask` is created, the configs
> > used
> > >>>> by
> > >>>>>>>>> `MirrorSourceTask` must contain `task.assigned.partitions`
> with a
> > >>>>>>>> non-empty
> > >>>>>>>>> value.
> > >>>>>>>>>
> > >>>>>>>>> Jun Rao <j...@confluent.io.invalid> 於 2025年7月22日 週二 上午5:14寫道:
> > >>>>>>>>>
> > >>>>>>>>>> Hi, Jiunn-Yang and Chia-Ping,
> > >>>>>>>>>>
> > >>>>>>>>>> Thanks for the reply.
> > >>>>>>>>>>
> > >>>>>>>>>> JR34. Hmm, it seems that the code in taskConfigs() could
> return
> > an
> > >>>>>> empty
> > >>>>>>>>>> list for a task if knownSourceTopicPartitions is less than
> > >> maxTasks,
> > >>>>>>>>>> Chia-Ping?
> > >>>>>>>>>>
> > >>>>>>>>>> JR36. Sounds good. Could you update the KIP? Also, should we
> do
> > >> the
> > >>>>>> same
> > >>>>>>>>>> for ssl.cipher.suites and sasl.oauthbearer.expected.audience?
> > >>>>>>>>>>
> > >>>>>>>>>> JR37. Is it true that MirrorClientConfig.bootstrap.servers
> > returns
> > >>>>>>>>>> ClassCastException for null? It seems that null could be
> casted
> > to
> > >>>> any
> > >>>>>>>>>> class.
> > >>>>>>>>>>
> > >>>>>>>>>> JR38. "If the configuration is optional, we will reject any
> > >>>> duplicate
> > >>>>>>>>>> values in the list." Could you clarify this? For example,
> > >>>> plugin.path
> > >>>>>> is
> > >>>>>>>>>> optional, but with a default value. We reject duplicates as
> well
> > >> as
> > >>>>>>>> empty
> > >>>>>>>>>> lists.
> > >>>>>>>>>>
> > >>>>>>>>>> JR39. isEmptyAllowed and isNullAllowed are not public fields,
> > >> right?
> > >>>>>>>> They
> > >>>>>>>>>> are only public in the anyNonDuplicateValues() method.
> > >>>>>>>>>>
> > >>>>>>>>>> JR40. It would be useful to mention that if cleanup.policy is
> > >> empty
> > >>>>>> and
> > >>>>>>>>>> remote.storage.enable is true, the local log segments will be
> > >>>> cleaned
> > >>>>>>>> based
> > >>>>>>>>>> on log.local.retention.bytes and log.local.retention.ms.
> > >>>>>>>>>>
> > >>>>>>>>>> Jun
> > >>>>>>>>>>
> > >>>>>>>>>> On Fri, Jul 18, 2025 at 9:52 AM Chia-Ping Tsai <
> > >> chia7...@gmail.com>
> > >>>>>>>> wrote:
> > >>>>>>>>>>
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> JR34: For these two configurations, setting an empty list
> > feels
> > >> a
> > >>>>>> bit
> > >>>>>>>>>>>> unintuitive. If an empty list is
> > >>>>>>>>>>>> provided, the consumer will call the unsubscribe method,
> which
> > >>>>>> doesn't
> > >>>>>>>>>>>> seem appropriate given
> > >>>>>>>>>>>> the documentation states: "Topic-partitions assigned to this
> > >> task
> > >>>> to
> > >>>>>>>>>>>> replicate."
> > >>>>>>>>>>>>
> > >>>>>>>>>>>
> > >>>>>>>>>>> agreed. Additionally, the source code [0] shows that it is
> not
> > >>>>>> intended
> > >>>>>>>>>> to
> > >>>>>>>>>>> generate empty tps for the source task
> > >>>>>>>>>>>
> > >>>>>>>>>>> [0]
> > >>>>>>>>>>>
> > >>>>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>
> > >>>>>>
> > >>>>
> > >>
> >
> https://github.com/apache/kafka/blob/9b542b6ea21e84677a9292f250fc25f8b4162e6f/connect/mirror/src/main/java/org/apache/kafka/connect/mirror/MirrorSourceConnector.java#L202
> > >>>>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>
> > >>>>
> > >>
> > >>
> >
> >
>

Reply via email to