-
Notifications
You must be signed in to change notification settings - Fork 15.4k
KAFKA-9437: KIP-559: Make the Kafka Protocol Friendlier with L7 Proxies #7994
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
effa65d
6988e54
525e84d
aa10086
832a6db
f345790
8c160c9
6b78131
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -574,7 +574,11 @@ private class JoinGroupResponseHandler extends CoordinatorResponseHandler<JoinGr | |
| @Override | ||
| public void handle(JoinGroupResponse joinResponse, RequestFuture<ByteBuffer> future) { | ||
| Errors error = joinResponse.error(); | ||
| if (error == Errors.NONE) { | ||
| if (isProtocolTypeInconsistent(joinResponse.data().protocolType())) { | ||
| log.debug("JoinGroup failed: Received inconsistent ProtocolType ({})", | ||
| joinResponse.data().protocolType()); | ||
| future.raise(Errors.INCONSISTENT_GROUP_PROTOCOL); | ||
| } else if (error == Errors.NONE) { | ||
| log.debug("Received successful JoinGroup response: {}", joinResponse); | ||
| sensors.joinSensor.record(response.requestLatencyMs()); | ||
|
|
||
|
|
@@ -654,6 +658,8 @@ private RequestFuture<ByteBuffer> onJoinFollower() { | |
| new SyncGroupRequestData() | ||
| .setGroupId(rebalanceConfig.groupId) | ||
| .setMemberId(generation.memberId) | ||
| .setProtocolType(protocolType()) | ||
| .setProtocolName(generation.protocol) | ||
| .setGroupInstanceId(this.rebalanceConfig.groupInstanceId.orElse(null)) | ||
| .setGenerationId(generation.generationId) | ||
| .setAssignments(Collections.emptyList()) | ||
|
|
@@ -681,6 +687,8 @@ private RequestFuture<ByteBuffer> onJoinLeader(JoinGroupResponse joinResponse) { | |
| new SyncGroupRequestData() | ||
| .setGroupId(rebalanceConfig.groupId) | ||
| .setMemberId(generation.memberId) | ||
| .setProtocolType(protocolType()) | ||
| .setProtocolName(generation.protocol) | ||
| .setGroupInstanceId(this.rebalanceConfig.groupInstanceId.orElse(null)) | ||
| .setGenerationId(generation.generationId) | ||
| .setAssignments(groupAssignmentList) | ||
|
|
@@ -704,7 +712,12 @@ private class SyncGroupResponseHandler extends CoordinatorResponseHandler<SyncGr | |
| public void handle(SyncGroupResponse syncResponse, | ||
| RequestFuture<ByteBuffer> future) { | ||
| Errors error = syncResponse.error(); | ||
| if (error == Errors.NONE) { | ||
| if (isProtocolTypeInconsistent(syncResponse.data.protocolType()) | ||
| || isProtocolNameInconsistent(syncResponse.data.protocolName())) { | ||
| log.debug("SyngGroup failed: Received inconsistent ProtocolType ({}) and/or ProtocolName ({})", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I'd suggest breaking this into two separate cases so that the user doesn't have to guess what was inconsistent. Also, can we include the expected value?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes sense. I will also include the expected value. |
||
| syncResponse.data.protocolType(), syncResponse.data.protocolName()); | ||
| future.raise(Errors.INCONSISTENT_GROUP_PROTOCOL); | ||
| } else if (error == Errors.NONE) { | ||
| sensors.syncSensor.record(response.requestLatencyMs()); | ||
| future.complete(ByteBuffer.wrap(syncResponse.data.assignment())); | ||
| } else { | ||
|
|
@@ -887,6 +900,14 @@ protected synchronized void requestRejoin() { | |
| this.rejoinNeeded = true; | ||
| } | ||
|
|
||
| private boolean isProtocolTypeInconsistent(String protocolType) { | ||
| return protocolType != null && !protocolType.equals(protocolType()); | ||
| } | ||
|
|
||
| private boolean isProtocolNameInconsistent(String protocolName) { | ||
| return protocolName != null && !protocolName.equals(generation().protocol); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we change
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Definitely. Good catch! |
||
| } | ||
|
|
||
| /** | ||
| * Close the coordinator, waiting if needed to send LeaveGroup. | ||
| */ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -81,6 +81,10 @@ public Map<String, ByteBuffer> groupAssignments() { | |
| return groupAssignments; | ||
| } | ||
|
|
||
| public boolean areProtocolTypeAndNamePresent() { | ||
|
dajac marked this conversation as resolved.
Outdated
|
||
| return version() >= 5 && (data.protocolType() == null || data.protocolName() == null); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The version check is probably not necessary. Also, shouldn't we be checking for non-null entries?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that we need the version check. Regarding the non-null entries, the verification (== provided values match the group's ones) is done in the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I'm missing something, but the function name suggests that it should return true if both the protocol type and name are non-null. The current logic returns true if either field is null. Are we missing a
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh... The name is indeed misleading. I have reworked this part a bit. Now, the function is called |
||
| } | ||
|
|
||
| public static SyncGroupRequest parse(ByteBuffer buffer, short version) { | ||
| return new SyncGroupRequest(ApiKeys.SYNC_GROUP.parseRequest(version, buffer), version); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,7 +29,9 @@ | |
| // Version 5 is bumped to apply group.instance.id to identify member across restarts. | ||
| // | ||
| // Version 6 is the first flexible version. | ||
| "validVersions": "0-6", | ||
| // | ||
| // Starting from version 7, the broker sends back the Protocol Type to the client (KIP-599). | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. KIP-559 (and elsewhere)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch! Thanks! |
||
| "validVersions": "0-7", | ||
| "flexibleVersions": "6+", | ||
| "fields": [ | ||
| { "name": "ThrottleTimeMs", "type": "int32", "versions": "2+", "ignorable": true, | ||
|
|
@@ -38,6 +40,9 @@ | |
| "about": "The error code, or 0 if there was no error." }, | ||
| { "name": "GenerationId", "type": "int32", "versions": "0+", "default": "-1", | ||
| "about": "The generation ID of the group." }, | ||
| { "name": "ProtocolType", "type": "string", "versions": "7+", | ||
| "nullableVersions": "7+", "default": "null", "ignorable": true, | ||
| "about": "The group protocol name." }, | ||
| { "name": "ProtocolName", "type": "string", "versions": "0+", | ||
| "about": "The group protocol selected by the coordinator." }, | ||
| { "name": "Leader", "type": "string", "versions": "0+", | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the error code should take precedence over this validation. Perhaps we do this only when the error is NONE? Similarly for the JoinGroup response.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. Let me do this.