KAFKA-20623: Wire topology description plugin into GroupCoordinatorService#22545
Draft
frankvicky wants to merge 1 commit into
Draft
KAFKA-20623: Wire topology description plugin into GroupCoordinatorService#22545frankvicky wants to merge 1 commit into
frankvicky wants to merge 1 commit into
Conversation
frankvicky
commented
Jun 11, 2026
| Objects.requireNonNull(name, "name"); | ||
| topics = Set.copyOf(Objects.requireNonNull(topics, "topics")); | ||
| successors = Set.copyOf(Objects.requireNonNull(successors, "successors")); | ||
| topics = Collections.unmodifiableSet(Objects.requireNonNull(topics, "topics")); |
Contributor
Author
There was a problem hiding this comment.
Set.copyOf doesn't guarantee the order, so I change to unmodifiableSet
dajac
reviewed
Jun 11, 2026
Comment on lines
+715
to
+716
| .withStreamsGroupTopologyDescriptionPlugin( | ||
| Optional.ofNullable(config.groupCoordinatorConfig.streamsGroupTopologyDescriptionPlugin(java.util.Map.of()))) |
Member
There was a problem hiding this comment.
I am not sure to follow why we need withStreamsGroupTopologyDescriptionPlugin. The build already gets the groupCoordinatorConfig. Can't we rely on it internally?
dajac
reviewed
Jun 11, 2026
| Group removed = groups.get(groupId, Long.MAX_VALUE); | ||
| groups.remove(groupId); | ||
| if (removed != null && removed.type() == Group.GroupType.STREAMS) { | ||
| streamsGroupRemovalListener.accept(groupId); |
Member
There was a problem hiding this comment.
Let's discuss this further. I would like to understand the rational. I think that we should try to avoid this kind of coupling from the shard to the service. It should be the other way around.
lucasbru
reviewed
Jun 12, 2026
| )); | ||
| } | ||
|
|
||
| /** |
Member
There was a problem hiding this comment.
I think it would be nice to move this to a separate class (like TopologyDescriptionManager)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
JIRA: KAFKA-20623 This PR is a part of KIP-1331.
Builder plumbing
GroupCoordinatorService.Builderaccepts anOptional<StreamsGroupTopologyDescriptionPlugin>and constructs theper-group back-off
state at build time so the shard-builder supplier closure can wire a
removal listener
back into it.
BrokerServerreadsgroupCoordinatorConfig.streamsGroupTopologyDescriptionPlugin(...)and passes the
resulting
Optionalthrough. When the config is unset the feature isfully disabled.
Heartbeat post-processing
StreamsGroupHeartbeatResultnow carriesstoredDescriptionTopologyEpochandfailedDescriptionTopologyEpochalongsidecurrentTopologyEpoch, sothe service layer
can decide whether to set
TopologyDescriptionRequired=truewithoutre-reading the
group.
maybeSetTopologyDescriptionRequiredapplies the KIP-1331 gating:plugin present,
response has no error code, c
initial delay; a successful push or a permanent plugin failure clears
the entry.
avoid leaking entries
for groups that vanish,
GroupMetadataManagernow exposes aConsumer<String>streams-group removal listener (wired through
GroupCoordinatorShard.Builder). Thelistener fires from
removeGroupwhenever the removed group is astreams group, and
from the
STREAMSbranch ofonUnloaded; the service registers it asbackoff::clear.StreamsGroupTopologyDescriptionUpdatehandlerinactive
(
COORDINATOR_NOT_AVAILABLE), no plugin is configured(
UNSUPPORTED_VERSION), orthe request is structurally malformed (
INVALID_REQUESTfor emptyMemberId,empty
GroupId, or nullTopologyDescription).validateStreamsGroupMemberfirst (so a fencedcaller gets
UNKNOWN_MEMBER_IDrather than anINVALID_REQUESTfrom a payloadconversion
failure), then converts the wire payload to the broker-side POJO, then
calls the
plugin.
StoredDescriptionTopologyEpoch;a
StreamsTopologyDescriptionPermanentFailureException(or asynchronous throw)
writes
FailedDescriptionTopologyEpoch; any other exception istreated as transient
and writes no record.
STREAMS_TOPOLOGY_DESCRIPTION_UPDATE_FAILEDwiththe plugin's message; the permanent-vs-transient split is
broker-internal.
whenComplete, drivenby a
BackoffActionholder populated by each terminal branch. Apost-plugin write failure
leaves the action at
ARM, so the next heartbeat sees the drift andre-solicits an
idempotent re-push, matching the KIP-1331 invariant.
DeleteGroupsintegrationstreams groups
with a non-default
StoredDescriptionTopologyEpoch(
streamsGroupsWithStoredTopologyDescription)and calls
plugin.deleteTopologyfor each in parallel.GROUP_DELETION_FAILEDwith thecause string in
ErrorMessage; the group is held back from tombstoning so the callercan retry.
Mixed batches are honoured: groups that succeed proceed to tombstone,
groups that fail
return the per-group error.
downgraded to
UNKNOWN_SERVER_ERRORwith no message, matching the convention usedby KIP-1043 for
new error codes that older request versions cannot interpret.
Wire ↔ POJO converter
StreamsGroupTopologyDescriptionConvertertranslatesStreamsGroupTopologyDescriptionUpdateRequestData.TopologyDescriptioninto the
broker-side
StreamsGroupTopologyDescriptionPOJO. Subtopology nodeordering and
string-collection iteration order are preserved via
LinkedHashSet,so a downstream
pretty-printer (e.g. the future
kafka-streams-groups.sh --topologycommand) can
reproduce the source ordering.
SOURCE=1,PROCESSOR=2,SINK=3) map to thesealed
Nodehierarchy.
GlobalStoreshape is validated; a malformed payloadthrows
InvalidRequestException.Reviewers: David Jacot david.jacot@gmail.com, Lucas Brutschy
lbrutschy@confluent.io