rishi-rana commented on code in PR #23530:
URL: https://github.com/apache/kafka/pull/23530#discussion_r4067631111


##########
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/GroupMetadataManager.java:
##########
@@ -5927,14 +5927,19 @@ public void replay(
                 return;
             }
 
-            if (oldMember.memberEpoch() != LEAVE_GROUP_MEMBER_EPOCH) {
-                throw new IllegalStateException("Received a tombstone record 
to delete member " + memberId
-                    + " but did not receive 
ConsumerGroupCurrentMemberAssignmentValue tombstone.");
-            }
-            if (consumerGroup.targetAssignment().containsKey(memberId)) {
-                throw new IllegalStateException("Received a tombstone record 
to delete member " + memberId
-                    + " but did not receive 
ConsumerGroupTargetAssignmentMetadataValue tombstone.");
+            if (oldMember.memberEpoch() != LEAVE_GROUP_MEMBER_EPOCH || 
consumerGroup.targetAssignment().containsKey(memberId)) {
+                List<String> reasons = new ArrayList<>();
+                if (oldMember.memberEpoch() != LEAVE_GROUP_MEMBER_EPOCH) {
+                    reasons.add("has invalid leave group epoch");
+                }
+                if (consumerGroup.targetAssignment().containsKey(memberId)) {
+                    reasons.add("member exists in target assignment");
+                }
+                log.warn("Received a tombstone record to delete consumer group 
member {} but member {};" +
+                        " the sibling tombstones were likely removed by 
compaction.",
+                    memberId, String.join(" and ", reasons));
             }
+
             consumerGroup.removeMember(memberId);

Review Comment:
   When this condition (line 5930: `targetAssignment().containsKey(memberId)`) 
is hit, this now warns and calls `removeMember(memberId)` — but 
`ConsumerGroup#removeMember` doesn't touch `targetAssignment` (same for 
`ShareGroup#removeMember` and `StreamsGroup#removeMember`), and nothing else 
will clean up that entry for a member that's already gone. So this leaves a 
permanently orphaned entry in `targetAssignment()`, not just a logged 
compaction-artifact warning.
   
   Should this also call `removeTargetAssignment(memberId)` (already available 
on the shared `ModernGroup` base class) here? Same question applies to the two 
sibling occurrences: share group (line 6352 condition / line 6365 
`removeMember` call) and streams group (line 6459 condition / line 6472 
`removeMember` call).



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to