diff --git a/ratis-server-api/src/main/java/org/apache/ratis/statemachine/StateMachine.java b/ratis-server-api/src/main/java/org/apache/ratis/statemachine/StateMachine.java index e21411ec79..90813f325b 100644 --- a/ratis-server-api/src/main/java/org/apache/ratis/statemachine/StateMachine.java +++ b/ratis-server-api/src/main/java/org/apache/ratis/statemachine/StateMachine.java @@ -228,6 +228,11 @@ default void notifyFollowerSlowness(RoleInfoProto leaderInfo) {} * Notify {@link StateMachine} that this server is no longer the leader. */ default void notifyNotLeader(Collection pendingEntries) throws IOException {} + + /** + * Notify the {@link StateMachine} that this server becomes ready after changed to leader. + */ + default void notifyLeaderReady() {} } /** 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 7ea4d738dc..7eb2559bbb 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 @@ -316,6 +316,7 @@ private List getFollowerInfos(PeerConfiguration peers) { private final int stagingCatchupGap; private final long placeHolderIndex; + private final AtomicBoolean isReady = new AtomicBoolean(); private final RaftServerMetricsImpl raftServerMetrics; private final LogAppenderMetrics logAppenderMetrics; private final long followerMaxGapThreshold; @@ -383,7 +384,14 @@ LogEntryProto start() { } boolean isReady() { - return server.getState().getLastAppliedIndex() >= placeHolderIndex; + return isReady.get(); + } + + void checkReady(LogEntryProto entry) { + if (entry.getTerm() == currentTerm && entry.getIndex() == placeHolderIndex) { + isReady.set(true); + server.getStateMachine().leaderEvent().notifyLeaderReady(); + } } void stop() { 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 add6b041da..7065993315 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 @@ -1802,6 +1802,7 @@ CompletableFuture applyLogToStateMachine(LogEntryProto next) throws Raf // the new conf in the metadata file and notify the StateMachine. state.writeRaftConfiguration(next); stateMachine.event().notifyConfigurationChanged(next.getTerm(), next.getIndex(), next.getConfigurationEntry()); + role.getLeaderState().ifPresent(leader -> leader.checkReady(next)); } else if (next.hasStateMachineLogEntry()) { // check whether there is a TransactionContext because we are the leader. TransactionContext trx = role.getLeaderState()