ahuang98 commented on code in PR #19590:
URL: https://github.com/apache/kafka/pull/19590#discussion_r2066930477


##########
metadata/src/main/java/org/apache/kafka/metadata/PartitionRegistration.java:
##########
@@ -165,8 +165,20 @@ public PartitionRegistration build() {
     public final int leaderEpoch;
     public final int partitionEpoch;
 
-    public static boolean electionWasClean(int newLeader, int[] isr, int[] 
elr) {
-        return newLeader == NO_LEADER || Replicas.contains(isr, newLeader) || 
Replicas.contains(elr, newLeader);
+    public static boolean electionWasClean(PartitionRegistration prev, 
PartitionRegistration next) {
+        int newLeader = next.leader;
+        // take current all replicas as ISR if prev is null (new created 
partition), so we won't treat it as unclean election.

Review Comment:
   nit: let's clarify the wording while we're here?
   
   `take all current replicas...`



##########
metadata/src/main/java/org/apache/kafka/metadata/PartitionRegistration.java:
##########
@@ -165,8 +165,20 @@ public PartitionRegistration build() {
     public final int leaderEpoch;
     public final int partitionEpoch;
 
-    public static boolean electionWasClean(int newLeader, int[] isr, int[] 
elr) {
-        return newLeader == NO_LEADER || Replicas.contains(isr, newLeader) || 
Replicas.contains(elr, newLeader);
+    public static boolean electionWasClean(PartitionRegistration prev, 
PartitionRegistration next) {
+        int newLeader = next.leader;
+        // take current all replicas as ISR if prev is null (new created 
partition), so we won't treat it as unclean election.
+        int[] prevIsr = prev != null ? prev.isr : next.replicas;
+        int[] prevElr = prev != null ? prev.elr : new int[]{};
+        int[] prevReplicas = prev != null ? prev.replicas : next.replicas;
+        boolean isReassignment = !Arrays.equals(prevReplicas, next.replicas);
+        // A reassignment can change the partition replicas, which also means 
it can change the preferred leader.
+        // When all the replicas required in the reassignment task is added to 
ISR, the reassignment will be completed.
+        // However, if the new preferred leader is the last one added to ISR, 
it will be also elected in the same
+        // partition change. In this case, the new leader will not be in the 
previous ISR.

Review Comment:
   `In this case, even though the new leader will not be in the previous ISR 
this should be treated as a clean election`?



##########
metadata/src/main/java/org/apache/kafka/metadata/PartitionRegistration.java:
##########
@@ -165,8 +165,20 @@ public PartitionRegistration build() {
     public final int leaderEpoch;
     public final int partitionEpoch;
 
-    public static boolean electionWasClean(int newLeader, int[] isr, int[] 
elr) {
-        return newLeader == NO_LEADER || Replicas.contains(isr, newLeader) || 
Replicas.contains(elr, newLeader);
+    public static boolean electionWasClean(PartitionRegistration prev, 
PartitionRegistration next) {
+        int newLeader = next.leader;
+        // take current all replicas as ISR if prev is null (new created 
partition), so we won't treat it as unclean election.
+        int[] prevIsr = prev != null ? prev.isr : next.replicas;
+        int[] prevElr = prev != null ? prev.elr : new int[]{};
+        int[] prevReplicas = prev != null ? prev.replicas : next.replicas;
+        boolean isReassignment = !Arrays.equals(prevReplicas, next.replicas);
+        // A reassignment can change the partition replicas, which also means 
it can change the preferred leader.
+        // When all the replicas required in the reassignment task is added to 
ISR, the reassignment will be completed.
+        // However, if the new preferred leader is the last one added to ISR, 
it will be also elected in the same
+        // partition change. In this case, the new leader will not be in the 
previous ISR.
+        // During a real unclean leader election, the reassignment will not 
complete.
+        return newLeader == NO_LEADER || Replicas.contains(prevIsr, newLeader) 
|| Replicas.contains(prevElr, newLeader) ||
+            isReassignment && Replicas.contains(next.isr, newLeader);

Review Comment:
   just double checking, if `newLeader` was not in the previous replica list, 
is it _always_ true that it will not be in `next.isr`? I'm trying to understand 
if it's possible to get a false negative where we report an unclean election as 
clean



-- 
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: jira-unsubscr...@kafka.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to