This is an automated email from the ASF dual-hosted git repository. williamsong pushed a commit to branch snapshot-branch2 in repository https://gitbox.apache.org/repos/asf/ratis.git
commit 60d520146ba26c6408bb7a6064280c51c79a8954 Author: Tsz-Wo Nicholas Sze <[email protected]> AuthorDate: Thu Jul 27 10:52:11 2023 -0700 RATIS-1858. Follower keeps logging first election timeout. (#894) --- .../org/apache/ratis/server/impl/RaftServerImpl.java | 8 +++++++- .../java/org/apache/ratis/server/impl/ServerState.java | 16 ++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) 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 295ddbc61..8f8c0a982 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 @@ -517,6 +517,12 @@ class RaftServerImpl implements RaftServer.Division, }); } + void setFirstElection(Object reason) { + if (firstElectionSinceStartup.compareAndSet(true, false)) { + LOG.info("{}: set firstElectionSinceStartup to false for {}", getMemberId(), reason); + } + } + /** * Change the server state to Follower if this server is in a different role or force is true. * @param newTerm The new term. @@ -545,7 +551,7 @@ class RaftServerImpl implements RaftServer.Division, role.shutdownFollowerState(); } role.startFollowerState(this, reason); - firstElectionSinceStartup.set(false); + setFirstElection(reason); } return metadataUpdated; } 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 ee0760f1e..281569190 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 @@ -75,7 +75,7 @@ class ServerState implements Closeable { /** local storage for log and snapshot */ private RaftStorageImpl storage; private final SnapshotManager snapshotManager; - private volatile Timestamp lastNoLeaderTime; + private final AtomicReference<Timestamp> lastNoLeaderTime; private final TimeDuration noLeaderTimeout; private final ReadRequests readRequests; @@ -151,7 +151,7 @@ class ServerState implements Closeable { snapshotManager = new SnapshotManager(id, storage.getStorageDir(), stateMachine.getStateMachineStorage()); // On start the leader is null, start the clock now - this.lastNoLeaderTime = Timestamp.currentTime(); + this.lastNoLeaderTime = new AtomicReference<>(Timestamp.currentTime()); this.noLeaderTimeout = RaftServerConfigKeys.Notification.noLeaderTimeout(prop); final LongSupplier getSnapshotIndexFromStateMachine = () -> Optional.ofNullable(stateMachine.getLatestSnapshot()) @@ -303,15 +303,15 @@ class ServerState implements Closeable { void setLeader(RaftPeerId newLeaderId, Object op) { final RaftPeerId oldLeaderId = leaderId.getAndSet(newLeaderId); if (!Objects.equals(oldLeaderId, newLeaderId)) { - String suffix; + final String suffix; if (newLeaderId == null) { // reset the time stamp when a null leader is assigned - lastNoLeaderTime = Timestamp.currentTime(); + lastNoLeaderTime.set(Timestamp.currentTime()); suffix = ""; } else { - Timestamp previous = lastNoLeaderTime; - lastNoLeaderTime = null; + final Timestamp previous = lastNoLeaderTime.getAndSet(null); suffix = ", leader elected after " + previous.elapsedTimeMs() + "ms"; + server.setFirstElection(op); server.getStateMachine().event().notifyLeaderChanged(getMemberId(), newLeaderId); } LOG.info("{}: change Leader from {} to {} at term {} for {}{}", @@ -323,14 +323,14 @@ class ServerState implements Closeable { } boolean shouldNotifyExtendedNoLeader() { - return Optional.ofNullable(lastNoLeaderTime) + return Optional.ofNullable(lastNoLeaderTime.get()) .map(Timestamp::elapsedTime) .filter(t -> t.compareTo(noLeaderTimeout) > 0) .isPresent(); } long getLastLeaderElapsedTimeMs() { - return Optional.ofNullable(lastNoLeaderTime).map(Timestamp::elapsedTimeMs).orElse(0L); + return Optional.ofNullable(lastNoLeaderTime.get()).map(Timestamp::elapsedTimeMs).orElse(0L); } void becomeLeader() {
