KAFKA-20790: Promote streams assignor API to public module - #22788
Conversation
mjsax
left a comment
There was a problem hiding this comment.
Made a pass... Curious to hear from others.
| @@ -24,6 +27,8 @@ | |||
| * | |||
| * @param members The member assignments keyed by member ID. | |||
| */ | |||
| @InterfaceAudience.Public | |||
| @InterfaceStability.Evolving | |||
| public record GroupAssignment(Map<String, MemberAssignment> members) { | |||
There was a problem hiding this comment.
The KIP defines this as a class, not a record. -- Given that this is an output/return type, not an input to the assignor, it might actually be ok to keep as record, and we could also update the KIP?
\cc @lianetm for input
There was a problem hiding this comment.
Thanks, I will update my kip and make it into a record.
There was a problem hiding this comment.
I didn't follow the KIP too closely but I think the reason we went with a class is that it's easier to evolve in the future. When adding a new field, we can add a constructor overload and initialize it with a sensible default, whereas a record will require constructor changes and break any code that tries to use the old constructor signature.
There was a problem hiding this comment.
so maybe it's easier to maintain for future evolving as a record? I can change it back and adding the corresponding code today
There was a problem hiding this comment.
When adding a new field, we can add a constructor overload and initialize it with a sensible default, whereas a record will require constructor changes and break any code that tries to use the old constructor signature.
record still allows to add an overloaded constructor... it's still true, that overall record is less flexible than class though, so I also don't have any objections to change all record types in public API to interface or class.
…get the actual warmuptask
|
Have updated base on your comment, plz take a look. thanks! @mjsax |
mjsax
left a comment
There was a problem hiding this comment.
Thanks Gabby. Made a pass. 95% LGTM.
| member.instanceId(), | ||
| member.rackId(), | ||
| targetAssignment.activeTasks(), | ||
| targetAssignment.standbyTasks(), |
There was a problem hiding this comment.
It seems odd to me, that we are passing the targetAssignment data here... This sounds like a bug to me? I believe we should pass in "current assignment" instead.
\cc @squah-confluent -- looking into code for KIP-848, it seems we are also passing the target assignment. Wondering why?
// Prepare the member spec for all members.
members.forEach((memberId, member) ->
memberSpecs.put(memberId, newMemberSubscriptionAndAssignment(
member,
targetAssignment.getOrDefault(memberId, Assignment.EMPTY),
topicResolver
))
);
There was a problem hiding this comment.
Looking into StickyTaskAssignor we use it in initialize() to compute "prev active tasks" and "prev standby tasks" but if we did not reconcile to the target assignment yet, we would be "sticky" for no reason...
There was a problem hiding this comment.
It's intentional and I don't recall the reasoning for it. It does lead to some weirdness, such as KAFKA-19405. I think we should discuss with @dajac.
…he/kafka/coordinator/group/api/streams/assignor/MemberAssignmentState.java Co-authored-by: Matthias J. Sax <mjsax@apache.org>
# Conflicts: # group-coordinator/group-coordinator-api/src/main/java/org/apache/kafka/coordinator/group/api/streams/assignor/MemberAssignmentState.java
…the assigned task
| ); | ||
| } | ||
|
|
||
| private static List<StreamsGroupDescribeResponseData.TaskOffset> taskOffsetsFromMap(Map<TaskId, Long> offsets) { |
There was a problem hiding this comment.
change here cause the taskoffset has been changed from Map<TaskId, Long> to Map<String, Map<Integer, Long>>
| copyTasks(newMemberAssignment.activeTasks()), | ||
| copyTasks(newMemberAssignment.standbyTasks()), | ||
| // Warm-up tasks are not assigned by the assignor; they are decided during reconciliation. | ||
| Map.of() |
There was a problem hiding this comment.
| Map.of() | |
| new HashMap() |
There was a problem hiding this comment.
Map.of() return an unmodifiable map. If we make the extra effort to deep copy active and standby tasks to ensure it's modifiable, we should also ensure it for warmup tasks?
mjsax
left a comment
There was a problem hiding this comment.
Left on minor comment, but we can also address in a follow up PR. Plan to merge after CI passed.
) Part of KIP-1357. This PR adds the newly defined public API as defined in KIP-1357 to support customer broker side "streams" task assignors. It also refactors the existing runtime code and StickyTaskAssignor to use/implement the new public APIs. `org.apache.kafka.coordinator.group.api.assignor.streams` (in `group-coordinator-api`), all annotated with `@InterfaceAudience.Public` and `@InterfaceStability.Evolving`. Also fixes a latent bug: the old code incorrectly passed the old target assignment into the assignor. This PR now ensures that we correctly pass the current assignment instead. Reviewers: Matthias J. Sax <matthias@confluent.io>, Sean Quah <squah@confluent.io>
| public GroupAssignment( | ||
| Map<String, MemberAssignment> members | ||
| ) { | ||
| this.members = Objects.requireNonNull(members); |
There was a problem hiding this comment.
Excuse me, it seems most public interfaces introduced by KIP-1357 use immutable collections, but this one does not. Would you mind sharing the reasoning with me?
There was a problem hiding this comment.
@gabriellefu -- Seems we missed this one. GroupAssignment is a return type from the assignor to the broker, so making a defensive copy using Map.copyOf(...) seems to be the right thing to do.
There was a problem hiding this comment.
The output side is currently guarded in TargetAssignmentBuilder, as TargetAssignmentBuilder#newMemberAssignment will deep copy the assignor's output using copyTasks(), so the server never holds a reference the assignor could mutate.
There was a problem hiding this comment.
I can do the change in a follow-up pr to make the api more aligned
Part of KIP-1357.
This PR adds the newly defined public API as defined in KIP-1357 to
support customer broker side "streams" task assignors. It also
refactors the existing runtime code and StickyTaskAssignor to
use/implement the new public APIs.
org.apache.kafka.coordinator.group.api.assignor.streams(ingroup-coordinator-api), all annotated with@InterfaceAudience.Publicand
@InterfaceStability.Evolving.Also fixes a latent bug: the old code incorrectly passed the old target
assignment into the assignor. This PR now ensures that we correctly pass
the current assignment instead.
Reviewers: Matthias J. Sax matthias@confluent.io, Sean Quah
squah@confluent.io