-
Notifications
You must be signed in to change notification settings - Fork 14.4k
KAFKA-19335: Membership managers send negative epoch in JOINING #19818
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
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 |
---|---|---|
|
@@ -312,6 +312,10 @@ private void assertTransitionToUnsubscribeOnHBSentAndWaitForResponseToCompleteLe | |
|
||
membershipManager.onHeartbeatSuccess(createShareGroupHeartbeatResponse(new ShareGroupHeartbeatResponseData.Assignment(), membershipManager.memberId())); | ||
|
||
assertFalse(sendLeave.isDone(), "Send leave operation should not complete until a leave response is received"); | ||
|
||
membershipManager.onHeartbeatSuccess(createShareGroupLeaveResponse(membershipManager.memberId())); | ||
|
||
assertSendLeaveCompleted(membershipManager, sendLeave); | ||
} | ||
|
||
|
@@ -518,6 +522,9 @@ public void testHeartbeatSuccessfulResponseWhenLeavingGroupCompletesLeave() { | |
assertFalse(leaveResult.isDone()); | ||
|
||
membershipManager.onHeartbeatSuccess(createShareGroupHeartbeatResponse(createAssignment(true), membershipManager.memberId())); | ||
assertFalse(leaveResult.isDone()); | ||
|
||
membershipManager.onHeartbeatSuccess(createShareGroupLeaveResponse(membershipManager.memberId())); | ||
assertSendLeaveCompleted(membershipManager, leaveResult); | ||
} | ||
|
||
|
@@ -561,10 +568,42 @@ public void testIgnoreHeartbeatResponseWhenNotInGroup(MemberState state) { | |
|
||
assertEquals(state, membershipManager.state()); | ||
verify(responseData, never()).memberId(); | ||
verify(responseData, never()).memberEpoch(); | ||
// In unsubscribed, we check if we received a leave group response, so we do verify member epoch. | ||
if (state != MemberState.UNSUBSCRIBED) { | ||
verify(responseData, never()).memberEpoch(); | ||
} | ||
verify(responseData, never()).assignment(); | ||
} | ||
|
||
@Test | ||
public void testIgnoreLeaveResponseWhenNotLeavingGroup() { | ||
ShareMembershipManager membershipManager = createMemberInStableState(); | ||
|
||
CompletableFuture<Void> leaveResult = membershipManager.leaveGroup(); | ||
|
||
// Send leave request, transitioning to UNSUBSCRIBED state | ||
membershipManager.onHeartbeatRequestGenerated(); | ||
assertEquals(MemberState.UNSUBSCRIBED, membershipManager.state()); | ||
|
||
// Receive a previous heartbeat response, which should be ignored | ||
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. This response is not "ignored" right, we are setting the member epoch in the response to 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 point. The comment didn't match what was being tested. I updated the test to include both a response that is ignored, and a response that actually unblocks the consumer. |
||
membershipManager.onHeartbeatSuccess(new ShareGroupHeartbeatResponse( | ||
new ShareGroupHeartbeatResponseData() | ||
.setErrorCode(Errors.NONE.code()) | ||
.setMemberId(membershipManager.memberId()) | ||
.setMemberEpoch(membershipManager.memberEpoch()) | ||
)); | ||
assertTrue(leaveResult.isDone()); | ||
|
||
// Share unblocks and updates subscription | ||
membershipManager.onSubscriptionUpdated(); | ||
membershipManager.onConsumerPoll(); | ||
|
||
membershipManager.onHeartbeatSuccess(createShareGroupLeaveResponse(membershipManager.memberId())); | ||
|
||
assertEquals(MemberState.JOINING, membershipManager.state()); | ||
assertEquals(0, membershipManager.memberEpoch()); | ||
} | ||
|
||
@Test | ||
public void testLeaveGroupWhenStateIsReconciling() { | ||
ShareMembershipManager membershipManager = mockJoinAndReceiveAssignment(false); | ||
|
@@ -1578,6 +1617,13 @@ private ShareGroupHeartbeatResponse createShareGroupHeartbeatResponse( | |
.setMemberEpoch(MEMBER_EPOCH) | ||
.setAssignment(assignment)); | ||
} | ||
|
||
private ShareGroupHeartbeatResponse createShareGroupLeaveResponse(String memberId) { | ||
return new ShareGroupHeartbeatResponse(new ShareGroupHeartbeatResponseData() | ||
.setErrorCode(Errors.NONE.code()) | ||
.setMemberId(memberId) | ||
.setMemberEpoch(ShareGroupHeartbeatRequest.LEAVE_GROUP_MEMBER_EPOCH)); | ||
} | ||
|
||
private ShareGroupHeartbeatResponse createShareGroupHeartbeatResponseWithError(String memberId) { | ||
return new ShareGroupHeartbeatResponse(new ShareGroupHeartbeatResponseData() | ||
|
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.
nit: The indentation of this line is now inconsistent with the rest of the method.
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.
Done