This is an automated email from the ASF dual-hosted git repository.
szetszwo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ratis.git
The following commit(s) were added to refs/heads/master by this push:
new c8f4c46b0 RATIS-1870. Refactor hasMajority code during configuration
changes. (#902)
c8f4c46b0 is described below
commit c8f4c46b06c85cf4ab950d33fc447eb01f71e953
Author: William Song <[email protected]>
AuthorDate: Tue Aug 15 02:15:39 2023 +0800
RATIS-1870. Refactor hasMajority code during configuration changes. (#902)
---
.../apache/ratis/server/impl/LeaderStateImpl.java | 33 ++--------------------
.../ratis/server/impl/PeerConfiguration.java | 16 +++++++----
.../ratis/server/impl/RaftConfigurationImpl.java | 20 +++++++++++++
3 files changed, 33 insertions(+), 36 deletions(-)
diff --git
a/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderStateImpl.java
b/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderStateImpl.java
index 7ea4d738d..5dfbc009b 100644
---
a/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderStateImpl.java
+++
b/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderStateImpl.java
@@ -875,36 +875,7 @@ class LeaderStateImpl implements LeaderState {
private boolean hasMajority(Predicate<RaftPeerId> isAcked) {
final RaftPeerId selfId = server.getId();
- final RaftConfigurationImpl conf = server.getRaftConf();
-
- final CurrentOldFollowerInfos infos =
followerInfoMap.getFollowerInfos(conf);
- final List<FollowerInfo> followers = infos.getCurrent();
- final boolean includeSelf = conf.containsInConf(selfId);
- final boolean newConf = hasMajority(isAcked, followers, includeSelf);
-
- if (!conf.isTransitional()) {
- return newConf;
- } else {
- final List<FollowerInfo> oldFollowers = infos.getOld();
- final boolean includeSelfInOldConf = conf.containsInOldConf(selfId);
- final boolean oldConf = hasMajority(isAcked, oldFollowers,
includeSelfInOldConf);
- return newConf && oldConf;
- }
- }
-
- private boolean hasMajority(Predicate<RaftPeerId> isAcked,
List<FollowerInfo> followers, boolean includeSelf) {
- if (followers.isEmpty() && !includeSelf) {
- return true;
- }
-
- int count = includeSelf ? 1 : 0;
- for (FollowerInfo follower: followers) {
- if (isAcked.test(follower.getId())) {
- count++;
- }
- }
- final int size = includeSelf ? followers.size() + 1 : followers.size();
- return count > size / 2;
+ return server.getRaftConf().hasMajority(isAcked, selfId);
}
private void updateCommit(LogEntryHeader[] entriesToCommit) {
@@ -1094,7 +1065,7 @@ class LeaderStateImpl implements LeaderState {
final long readIndex = server.getRaftLog().getLastCommittedIndex();
// if group contains only one member, fast path
- if (server.getRaftConf().getCurrentPeers().size() == 1) {
+ if (server.getRaftConf().isSingleton()) {
return CompletableFuture.completedFuture(readIndex);
}
diff --git
a/ratis-server/src/main/java/org/apache/ratis/server/impl/PeerConfiguration.java
b/ratis-server/src/main/java/org/apache/ratis/server/impl/PeerConfiguration.java
index 38e3602e8..600667c38 100644
---
a/ratis-server/src/main/java/org/apache/ratis/server/impl/PeerConfiguration.java
+++
b/ratis-server/src/main/java/org/apache/ratis/server/impl/PeerConfiguration.java
@@ -31,6 +31,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
+import java.util.function.Predicate;
import java.util.stream.Stream;
/**
@@ -150,12 +151,17 @@ class PeerConfiguration {
boolean hasMajority(Collection<RaftPeerId> others, RaftPeerId selfId) {
Preconditions.assertTrue(!others.contains(selfId));
- int num = 0;
- if (contains(selfId)) {
- num++;
+ return hasMajority(others::contains, contains(selfId));
+ }
+
+ boolean hasMajority(Predicate<RaftPeerId> activePeers, boolean includeSelf) {
+ if (peers.isEmpty() && !includeSelf) {
+ return true;
}
- for (RaftPeerId other : others) {
- if (contains(other)) {
+
+ int num = includeSelf ? 1 : 0;
+ for (RaftPeerId peerId: peers.keySet()) {
+ if (activePeers.test(peerId)) {
num++;
}
}
diff --git
a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftConfigurationImpl.java
b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftConfigurationImpl.java
index da9481a2e..aba5ae176 100644
---
a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftConfigurationImpl.java
+++
b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftConfigurationImpl.java
@@ -30,6 +30,7 @@ import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -238,6 +239,20 @@ final class RaftConfigurationImpl implements
RaftConfiguration {
(oldConf == null || oldConf.hasMajority(others, selfId));
}
+ /** @return true if the self id together with the acknowledged followers
reach majority. */
+ boolean hasMajority(Predicate<RaftPeerId> followers, RaftPeerId selfId) {
+ final boolean includeInCurrent = containsInConf(selfId);
+ final boolean hasMajorityInNewConf = conf.hasMajority(followers,
includeInCurrent);
+
+ if (!isTransitional()) {
+ return hasMajorityInNewConf;
+ } else {
+ final boolean includeInOldConf = containsInOldConf(selfId);
+ final boolean hasMajorityInOldConf = oldConf.hasMajority(followers,
includeInOldConf);
+ return hasMajorityInOldConf && hasMajorityInNewConf;
+ }
+ }
+
int getMajorityCount() {
return conf.getMajorityCount();
}
@@ -248,6 +263,11 @@ final class RaftConfigurationImpl implements
RaftConfiguration {
(oldConf != null && oldConf.majorityRejectVotes(rejects));
}
+ /** @return true if only one voting member (the leader) in the cluster */
+ boolean isSingleton() {
+ return getCurrentPeers().size() == 1 && getPreviousPeers().size() <= 1;
+ }
+
@Override
public String toString() {
return logEntryIndex + ": " + conf + ", old=" + oldConf;