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 <[email protected]>
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();
     }

Reply via email to