jsancio commented on code in PR #17728:
URL: https://github.com/apache/kafka/pull/17728#discussion_r1888921311


##########
raft/src/main/java/org/apache/kafka/raft/internals/VoterSetHistory.java:
##########
@@ -47,24 +47,6 @@ public final class VoterSetHistory {
      * @throws IllegalArgumentException if the offset is not greater than all 
previous offsets
      */
     public void addAt(long offset, VoterSet voters) {
-        Optional<LogHistory.Entry<VoterSet>> lastEntry = 
votersHistory.lastEntry();
-        if (lastEntry.isPresent() && lastEntry.get().offset() >= 0) {
-            // If the last voter set comes from the replicated log then the 
majorities must overlap.
-            // This ignores the static voter set and the bootstrapped voter 
set since they come from
-            // the configuration and the KRaft leader never guaranteed that 
they are the same across
-            // all replicas.
-            VoterSet lastVoterSet = lastEntry.get().value();
-            if (!lastVoterSet.hasOverlappingMajority(voters)) {
-                throw new IllegalArgumentException(
-                    String.format(
-                        "Last voter set %s doesn't have an overlapping 
majority with the new voter set %s",
-                        lastVoterSet,
-                        voters
-                    )
-                );

Review Comment:
   Instead of removing this check and throwing an exception. We can instead log 
the same message at INFO.
   
   You can create the `Logger` from passing the `LogContext` to this type's 
constructor.



##########
raft/src/main/java/org/apache/kafka/raft/VoterSet.java:
##########
@@ -270,26 +269,6 @@ public VotersRecord toVotersRecord(short version) {
             .setVoters(voterRecordVoters);
     }
 
-    /**
-     * Determines if two sets of voters have an overlapping majority.
-     *
-     * An overlapping majority means that for all majorities in {@code this} 
set of voters and for
-     * all majority in {@code that} set of voters, they have at least one 
voter in common.
-     *
-     * If this function returns true, it means that if one of the set of 
voters commits an offset,
-     * the other set of voters cannot commit a conflicting offset.
-     *
-     * @param that the other voter set to compare
-     * @return true if they have an overlapping majority, false otherwise
-     */
-    public boolean hasOverlappingMajority(VoterSet that) {
-        Set<ReplicaKey> thisReplicaKeys = voterKeys();
-        Set<ReplicaKey> thatReplicaKeys = that.voterKeys();
-
-        if (Utils.diff(HashSet::new, thisReplicaKeys, thatReplicaKeys).size() 
> 1) return false;
-        return Utils.diff(HashSet::new, thatReplicaKeys, 
thisReplicaKeys).size() <= 1;
-    }

Review Comment:
   See my other message but let's keep this functionality.



##########
raft/src/test/java/org/apache/kafka/raft/internals/VoterSetHistoryTest.java:
##########
@@ -122,55 +143,6 @@ void testBootstrapAddAt() {
         assertEquals(Optional.of(removedVoterSet), 
votersHistory.valueAtOrBefore(200));
     }
 
-    @Test
-    void testAddAtNonOverlapping() {
-        VoterSetHistory votersHistory = new VoterSetHistory(VoterSet.empty());
-
-        Map<Integer, VoterSet.VoterNode> voterMap = 
VoterSetTest.voterMap(IntStream.of(1, 2, 3), true);
-        VoterSet voterSet = VoterSet.fromMap(new HashMap<>(voterMap));
-
-        // Add a starting voter to the history
-        votersHistory.addAt(100, voterSet);
-
-        // Remove voter so that it doesn't overlap
-        VoterSet nonoverlappingRemovedSet = voterSet
-            .removeVoter(voterMap.get(1).voterKey()).get()
-            .removeVoter(voterMap.get(2).voterKey()).get();
-
-        assertThrows(
-            IllegalArgumentException.class,
-            () -> votersHistory.addAt(200, nonoverlappingRemovedSet)
-        );
-        assertEquals(voterSet, votersHistory.lastValue());
-
-
-        // Add voters so that it doesn't overlap
-        VoterSet nonoverlappingAddSet = voterSet
-            .addVoter(VoterSetTest.voterNode(4, true)).get()
-            .addVoter(VoterSetTest.voterNode(5, true)).get();
-
-        assertThrows(
-            IllegalArgumentException.class,
-            () -> votersHistory.addAt(200, nonoverlappingAddSet)
-        );
-        assertEquals(voterSet, votersHistory.lastValue());
-    }
-
-    @Test
-    void testNonoverlappingFromStaticVoterSet() {
-        Map<Integer, VoterSet.VoterNode> voterMap = 
VoterSetTest.voterMap(IntStream.of(1, 2, 3), true);
-        VoterSet staticVoterSet = VoterSet.fromMap(new HashMap<>(voterMap));
-        VoterSetHistory votersHistory = new VoterSetHistory(VoterSet.empty());
-
-        // Remove voter so that it doesn't overlap
-        VoterSet nonoverlappingRemovedSet = staticVoterSet
-            .removeVoter(voterMap.get(1).voterKey()).get()
-            .removeVoter(voterMap.get(2).voterKey()).get();
-
-        votersHistory.addAt(100, nonoverlappingRemovedSet);
-        assertEquals(nonoverlappingRemovedSet, votersHistory.lastValue());
-    }

Review Comment:
   This test is still correct after your change and after my suggestions. Let's 
keep this change.



##########
raft/src/test/java/org/apache/kafka/raft/VoterSetTest.java:
##########
@@ -258,76 +258,6 @@ void testRecordRoundTrip() {
         assertEquals(voterSet, 
VoterSet.fromVotersRecord(voterSet.toVotersRecord((short) 0)));
     }
 
-    @Test
-    void testOverlappingMajority() {

Review Comment:
   Let's keep all of these tests now that we are keeping the 
`hasOverlappingMajority` method.



##########
raft/src/test/java/org/apache/kafka/raft/internals/VoterSetHistoryTest.java:
##########
@@ -89,6 +89,27 @@ void testAddAt() {
         assertEquals(Optional.empty(), votersHistory.valueAtOrBefore(99));
         assertEquals(Optional.of(addedVoterSet), 
votersHistory.valueAtOrBefore(199));
         assertEquals(Optional.of(removedVoterSet), 
votersHistory.valueAtOrBefore(200));
+
+        // Assert multiple voters can be added or removed at a time
+        voterMap.put(4, VoterSetTest.voterNode(4, true));
+        voterMap.put(5, VoterSetTest.voterNode(5, true));
+
+        VoterSet addedMultipleVoters = VoterSet.fromMap(new 
HashMap<>(voterMap));
+        votersHistory.addAt(300, addedMultipleVoters);
+
+        assertEquals(addedMultipleVoters, votersHistory.lastValue());
+        assertEquals(Optional.of(removedVoterSet), 
votersHistory.valueAtOrBefore(299));
+        assertEquals(Optional.of(addedMultipleVoters), 
votersHistory.valueAtOrBefore(300));
+
+        voterMap.remove(4);
+        voterMap.remove(5);
+
+        VoterSet removedMultipleVoters = VoterSet.fromMap(new 
HashMap<>(voterMap));
+        votersHistory.addAt(400, removedMultipleVoters);
+
+        assertEquals(removedMultipleVoters, votersHistory.lastValue());
+        assertEquals(Optional.of(addedMultipleVoters), 
votersHistory.valueAtOrBefore(399));
+        assertEquals(Optional.of(removedMultipleVoters), 
votersHistory.valueAtOrBefore(400));
     }

Review Comment:
   The test looks good but let's put it in a separate test that is checking 
this case specifically. This test is already getting hard to read.



-- 
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