You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ratis.apache.org by sz...@apache.org on 2023/03/22 08:20:23 UTC
[ratis] 07/18: RATIS-1796. Fix TransferLeadership stopped by heartbeat from old leader (#844)
This is an automated email from the ASF dual-hosted git repository.
szetszwo pushed a commit to branch branch-2_readIndex
in repository https://gitbox.apache.org/repos/asf/ratis.git
commit ee8aef255cf622c49297ca7b90d44db06c5dfe6d
Author: Kaijie Chen <ck...@apache.org>
AuthorDate: Tue Mar 14 10:18:23 2023 +0800
RATIS-1796. Fix TransferLeadership stopped by heartbeat from old leader (#844)
(cherry picked from commit 05c0db0444eaade1b18e49465c3cde2ea5336485)
---
.../org/apache/ratis/server/impl/LeaderElection.java | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderElection.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderElection.java
index 5f79940cb..86ec62325 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderElection.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderElection.java
@@ -187,16 +187,23 @@ class LeaderElection implements Runnable {
private final RaftServerImpl server;
private final boolean skipPreVote;
+ private final ConfAndTerm round0;
- LeaderElection(RaftServerImpl server, boolean skipPreVote) {
+ LeaderElection(RaftServerImpl server, boolean force) {
this.name = server.getMemberId() + "-" + JavaUtils.getClassSimpleName(getClass()) + COUNT.incrementAndGet();
this.lifeCycle = new LifeCycle(this);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.server = server;
- this.skipPreVote = skipPreVote ||
+ this.skipPreVote = force ||
!RaftServerConfigKeys.LeaderElection.preVote(
server.getRaftServer().getProperties());
+ try {
+ // increase term of the candidate in advance if it's forced to election
+ this.round0 = force ? server.getState().initElection(Phase.ELECTION) : null;
+ } catch (IOException e) {
+ throw new IllegalStateException(name + ": Failed to initialize election", e);
+ }
}
void start() {
@@ -303,7 +310,10 @@ class LeaderElection implements Runnable {
if (!shouldRun()) {
return false;
}
- final ConfAndTerm confAndTerm = server.getState().initElection(phase);
+ // If round0 is non-null, we have already called initElection in the constructor,
+ // reuse round0 to avoid initElection again for the first round
+ final ConfAndTerm confAndTerm = (round == 0 && round0 != null) ?
+ round0 : server.getState().initElection(phase);
electionTerm = confAndTerm.getTerm();
conf = confAndTerm.getConf();
}