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 2019/07/22 21:08:10 UTC

[incubator-ratis] branch master updated: RATIS-596. Rename raft.server.leader.election.timeout.

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/incubator-ratis.git


The following commit(s) were added to refs/heads/master by this push:
     new 7c7cd28  RATIS-596. Rename raft.server.leader.election.timeout.
7c7cd28 is described below

commit 7c7cd28879291a53da955c2827bda5b0f93bb46f
Author: Tsz Wo Nicholas Sze <sz...@apache.org>
AuthorDate: Mon Jul 22 13:59:46 2019 -0700

    RATIS-596. Rename raft.server.leader.election.timeout.
---
 .../apache/ratis/server/RaftServerConfigKeys.java  | 28 ++++++++++++----------
 .../apache/ratis/server/impl/RaftServerImpl.java   |  2 +-
 .../org/apache/ratis/server/impl/ServerState.java  | 14 ++++++-----
 ...out.java => TestRaftServerNoLeaderTimeout.java} | 22 ++++++++---------
 4 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/ratis-server/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java b/ratis-server/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
index c077041..90a3134 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
@@ -73,19 +73,6 @@ public interface RaftServerConfigKeys {
     setInt(properties::setInt, STAGING_CATCHUP_GAP_KEY, stagingCatchupGap);
   }
 
-  /**
-   * Timeout for leader election after which the statemachine of the server is notified
-   * about leader election pending for a long time.
-   */
-  String LEADER_ELECTION_TIMEOUT_KEY = PREFIX + ".leader.election.timeout";
-  TimeDuration LEADER_ELECTION_TIMEOUT_DEFAULT = TimeDuration.valueOf(60, TimeUnit.SECONDS);
-  static TimeDuration leaderElectionTimeout(RaftProperties properties) {
-    return getTimeDuration(properties.getTimeDuration(LEADER_ELECTION_TIMEOUT_DEFAULT.getUnit()),
-        LEADER_ELECTION_TIMEOUT_KEY, LEADER_ELECTION_TIMEOUT_DEFAULT, getDefaultLog());
-  }
-  static void setLeaderElectionTimeout(RaftProperties properties, TimeDuration leaderElectionTimeout) {
-    setTimeDuration(properties::setTimeDuration, LEADER_ELECTION_TIMEOUT_KEY, leaderElectionTimeout);
-  }
 
   interface Write {
     String PREFIX = RaftServerConfigKeys.PREFIX + ".write";
@@ -420,6 +407,21 @@ public interface RaftServerConfigKeys {
     }
   }
 
+  interface Notification {
+    String PREFIX = RaftServerConfigKeys.PREFIX + "." + Notification.class.getSimpleName().toLowerCase();
+
+    /** Timeout value to notify the state machine when there is no leader. */
+    String NO_LEADER_TIMEOUT_KEY = PREFIX + ".no-leader.timeout";
+    TimeDuration NO_LEADER_TIMEOUT_DEFAULT = TimeDuration.valueOf(60, TimeUnit.SECONDS);
+    static TimeDuration noLeaderTimeout(RaftProperties properties) {
+      return getTimeDuration(properties.getTimeDuration(NO_LEADER_TIMEOUT_DEFAULT.getUnit()),
+          NO_LEADER_TIMEOUT_KEY, NO_LEADER_TIMEOUT_DEFAULT, getDefaultLog());
+    }
+    static void setNoLeaderTimeout(RaftProperties properties, TimeDuration leaderElectionTimeout) {
+      setTimeDuration(properties::setTimeDuration, NO_LEADER_TIMEOUT_KEY, leaderElectionTimeout);
+    }
+  }
+
   static void main(String[] args) {
     printAll(RaftServerConfigKeys.class);
   }
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java
index 9845b85..6b3b626 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java
@@ -406,7 +406,7 @@ public class RaftServerImpl implements RaftServerProtocol, RaftServerAsynchronou
     Preconditions.assertTrue(isFollower());
     role.shutdownFollowerState();
     setRole(RaftPeerRole.CANDIDATE, "changeToCandidate");
-    if (state.checkForExtendedNoLeader()) {
+    if (state.shouldNotifyExtendedNoLeader()) {
       stateMachine.notifyExtendedNoLeader(getRoleInfoProto());
     }
     // start election
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
index 7fbbc66..96e0d83 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
@@ -30,6 +30,7 @@ import org.apache.ratis.proto.RaftProtos.LogEntryProto;
 import org.apache.ratis.statemachine.SnapshotInfo;
 import org.apache.ratis.statemachine.StateMachine;
 import org.apache.ratis.statemachine.TransactionContext;
+import org.apache.ratis.util.TimeDuration;
 import org.apache.ratis.util.Timestamp;
 
 import java.io.Closeable;
@@ -43,7 +44,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Consumer;
@@ -66,7 +66,7 @@ public class ServerState implements Closeable {
   private final RaftStorage storage;
   private final SnapshotManager snapshotManager;
   private volatile Timestamp lastNoLeaderTime;
-  private final long leaderElectionTimeoutMs;
+  private final TimeDuration noLeaderTimeout;
 
   /**
    * Latest term server has seen.
@@ -113,8 +113,7 @@ public class ServerState implements Closeable {
     // On start the leader is null, start the clock now
     leaderId = null;
     this.lastNoLeaderTime = Timestamp.currentTime();
-    this.leaderElectionTimeoutMs =
-        RaftServerConfigKeys.leaderElectionTimeout(prop).toIntExact(TimeUnit.MILLISECONDS);
+    this.noLeaderTimeout = RaftServerConfigKeys.Notification.noLeaderTimeout(prop);
 
     // we cannot apply log entries to the state machine in this step, since we
     // do not know whether the local log entries have been committed.
@@ -262,8 +261,11 @@ public class ServerState implements Closeable {
     }
   }
 
-  boolean checkForExtendedNoLeader() {
-    return getLastLeaderElapsedTimeMs() > leaderElectionTimeoutMs;
+  boolean shouldNotifyExtendedNoLeader() {
+    return Optional.ofNullable(lastNoLeaderTime)
+        .map(Timestamp::elapsedTime)
+        .filter(t -> t.compareTo(noLeaderTimeout) > 0)
+        .isPresent();
   }
 
   long getLastLeaderElapsedTimeMs() {
diff --git a/ratis-test/src/test/java/org/apache/ratis/TestRaftServerLeaderElectionTimeout.java b/ratis-test/src/test/java/org/apache/ratis/TestRaftServerNoLeaderTimeout.java
similarity index 83%
rename from ratis-test/src/test/java/org/apache/ratis/TestRaftServerLeaderElectionTimeout.java
rename to ratis-test/src/test/java/org/apache/ratis/TestRaftServerNoLeaderTimeout.java
index afe7f32..7e1ecb7 100644
--- a/ratis-test/src/test/java/org/apache/ratis/TestRaftServerLeaderElectionTimeout.java
+++ b/ratis-test/src/test/java/org/apache/ratis/TestRaftServerNoLeaderTimeout.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -39,22 +39,21 @@ import java.util.concurrent.TimeUnit;
 /**
  * Test Raft Server Leader election timeout detection and notification to state machine.
  */
-public class TestRaftServerLeaderElectionTimeout extends BaseTest {
+public class TestRaftServerNoLeaderTimeout extends BaseTest {
   static {
     LogUtils.setLogLevel(RaftServerImpl.LOG, Level.DEBUG);
     LogUtils.setLogLevel(RaftClient.LOG, Level.DEBUG);
   }
 
-  public static final int NUM_SERVERS = 3;
+  private static final int NUM_SERVERS = 3;
 
-  protected static final RaftProperties properties = new RaftProperties();
+  private static final RaftProperties properties = new RaftProperties();
 
   private final MiniRaftClusterWithSimulatedRpc cluster = MiniRaftClusterWithSimulatedRpc
       .FACTORY.newCluster(NUM_SERVERS, getProperties());
 
-  public RaftProperties getProperties() {
-    RaftServerConfigKeys
-        .setLeaderElectionTimeout(properties, TimeDuration.valueOf(1, TimeUnit.SECONDS));
+  private static RaftProperties getProperties() {
+    RaftServerConfigKeys.Notification.setNoLeaderTimeout(properties, TimeDuration.valueOf(1, TimeUnit.SECONDS));
     properties.setClass(MiniRaftCluster.STATEMACHINE_CLASS_KEY,
         SimpleStateMachine4Testing.class, StateMachine.class);
     return properties;
@@ -76,8 +75,7 @@ public class TestRaftServerLeaderElectionTimeout extends BaseTest {
   @Test
   public void testLeaderElectionDetection() throws Exception {
     RaftTestUtil.waitForLeader(cluster);
-    long leaderElectionTimeout = RaftServerConfigKeys.
-        leaderElectionTimeout(cluster.getProperties()).toIntExact(TimeUnit.MILLISECONDS);
+    final TimeDuration noLeaderTimeout = RaftServerConfigKeys.Notification.noLeaderTimeout(cluster.getProperties());
 
     RaftServerImpl healthyFollower = cluster.getFollowers().get(1);
     RaftServerImpl failedFollower = cluster.getFollowers().get(0);
@@ -87,13 +85,15 @@ public class TestRaftServerLeaderElectionTimeout extends BaseTest {
     cluster.killServer(cluster.getLeader().getId());
 
     // Wait to ensure that leader election is triggered and also state machine callback is triggered
-    Thread.sleep( leaderElectionTimeout * 2);
+    noLeaderTimeout.sleep();
+    noLeaderTimeout.sleep();
 
     RaftProtos.RoleInfoProto roleInfoProto =
         SimpleStateMachine4Testing.get(healthyFollower).getLeaderElectionTimeoutInfo();
     Assert.assertNotNull(roleInfoProto);
 
     Assert.assertEquals(roleInfoProto.getRole(), RaftProtos.RaftPeerRole.CANDIDATE);
-    Assert.assertTrue(roleInfoProto.getCandidateInfo().getLastLeaderElapsedTimeMs() > leaderElectionTimeout);
+    final long noLeaderTimeoutMs = noLeaderTimeout.toLong(TimeUnit.MILLISECONDS);
+    Assert.assertTrue(roleInfoProto.getCandidateInfo().getLastLeaderElapsedTimeMs() > noLeaderTimeoutMs);
   }
 }