This is an automated email from the ASF dual-hosted git repository.

williamsong pushed a commit to branch snapshot-3
in repository https://gitbox.apache.org/repos/asf/ratis.git

commit 21271d60029e6e3f03d7651378974ece7bef519a
Author: Potato <[email protected]>
AuthorDate: Sun Mar 24 02:11:39 2024 +0800

    RATIS-2036. Avoid trigger snapshot when removing raftGroup (#1055)
---
 .../apache/ratis/server/RaftServerConfigKeys.java  | 12 ++++++++++
 .../apache/ratis/server/impl/RaftServerImpl.java   |  1 +
 .../ratis/server/impl/StateMachineUpdater.java     | 28 +++++++++++++++++++++-
 3 files changed, 40 insertions(+), 1 deletion(-)

diff --git 
a/ratis-server-api/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
 
b/ratis-server-api/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
index 565e88126..7419ca095 100644
--- 
a/ratis-server-api/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
+++ 
b/ratis-server-api/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
@@ -647,6 +647,18 @@ public interface RaftServerConfigKeys {
       setBoolean(properties::setBoolean, TRIGGER_WHEN_STOP_ENABLED_KEY, 
triggerWhenStopEnabled);
     }
 
+    /** whether trigger snapshot when remove raft server */
+    String TRIGGER_WHEN_REMOVE_ENABLED_KEY = PREFIX + 
".trigger-when-remove.enabled";
+    /** by default let the state machine to trigger snapshot when remove */
+    boolean TRIGGER_WHEN_REMOVE_ENABLED_DEFAULT = true;
+    static boolean triggerWhenRemoveEnabled(RaftProperties properties) {
+      return getBoolean(properties::getBoolean,
+          TRIGGER_WHEN_REMOVE_ENABLED_KEY, 
TRIGGER_WHEN_REMOVE_ENABLED_DEFAULT, getDefaultLog());
+    }
+    static void setTriggerWhenRemoveEnabled(RaftProperties properties, boolean 
triggerWhenRemoveEnabled) {
+      setBoolean(properties::setBoolean, TRIGGER_WHEN_REMOVE_ENABLED_KEY, 
triggerWhenRemoveEnabled);
+    }
+
     /** The log index gap between to two snapshot creations. */
     String CREATION_GAP_KEY = PREFIX + ".creation.gap";
     long CREATION_GAP_DEFAULT = 1024;
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 ed5457b3d..4ae60acaa 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
@@ -487,6 +487,7 @@ class RaftServerImpl implements RaftServer.Division,
     final RaftStorageDirectory dir = state.getStorage().getStorageDir();
 
     /* Shutdown is triggered here inorder to avoid any locked files. */
+    state.getStateMachineUpdater().setRemoving();
     close();
     getStateMachine().event().notifyGroupRemove();
     if (deleteDirectory) {
diff --git 
a/ratis-server/src/main/java/org/apache/ratis/server/impl/StateMachineUpdater.java
 
b/ratis-server/src/main/java/org/apache/ratis/server/impl/StateMachineUpdater.java
index 43fbdd884..5affbc3a7 100644
--- 
a/ratis-server/src/main/java/org/apache/ratis/server/impl/StateMachineUpdater.java
+++ 
b/ratis-server/src/main/java/org/apache/ratis/server/impl/StateMachineUpdater.java
@@ -74,6 +74,8 @@ class StateMachineUpdater implements Runnable {
 
   private final boolean triggerSnapshotWhenStopEnabled;
 
+  private final boolean triggerSnapshotWhenRemoveEnabled;
+
   private final Long autoSnapshotThreshold;
   private final boolean purgeUptoSnapshotIndex;
 
@@ -91,6 +93,8 @@ class StateMachineUpdater implements Runnable {
 
   private final Consumer<Long> appliedIndexConsumer;
 
+  private volatile boolean isRemoving;
+
   StateMachineUpdater(StateMachine stateMachine, RaftServerImpl server,
       ServerState serverState, long lastAppliedIndex, RaftProperties 
properties, Consumer<Long> appliedIndexConsumer) {
     this.name = serverState.getMemberId() + "-" + 
JavaUtils.getClassSimpleName(getClass());
@@ -106,6 +110,7 @@ class StateMachineUpdater implements Runnable {
     this.snapshotIndex = new RaftLogIndex("snapshotIndex", lastAppliedIndex);
 
     this.triggerSnapshotWhenStopEnabled = 
RaftServerConfigKeys.Snapshot.triggerWhenStopEnabled(properties);
+    this.triggerSnapshotWhenRemoveEnabled = 
RaftServerConfigKeys.Snapshot.triggerWhenRemoveEnabled(properties);
     final boolean autoSnapshot = 
RaftServerConfigKeys.Snapshot.autoTriggerEnabled(properties);
     this.autoSnapshotThreshold = autoSnapshot? 
RaftServerConfigKeys.Snapshot.autoTriggerThreshold(properties): null;
     final int numSnapshotFilesRetained = 
RaftServerConfigKeys.Snapshot.retentionFileNum(properties);
@@ -320,12 +325,33 @@ class StateMachineUpdater implements Runnable {
     if (autoSnapshotThreshold == null) {
       return false;
     } else if (shouldStop()) {
-      return triggerSnapshotWhenStopEnabled && getLastAppliedIndex() - 
snapshotIndex.get() > 0;
+      return shouldTakeSnapshotAtStop() && getLastAppliedIndex() - 
snapshotIndex.get() > 0;
     }
     return state == State.RUNNING &&
         getStateMachineLastAppliedIndex() - snapshotIndex.get() >= 
autoSnapshotThreshold;
   }
 
+  /**
+   * In view of the three variables triggerSnapshotWhenStopEnabled, 
triggerSnapshotWhenRemoveEnabled and isRemoving,
+   * we can draw the following 8 combination:
+   * true true true => true
+   * true true false => true
+   * true false true => false
+   * true false false => true
+   * false true true => true
+   * false true false =>  false
+   * false false true => false
+   * false false false => false
+   * @return result
+   */
+  private boolean shouldTakeSnapshotAtStop() {
+    return isRemoving ? triggerSnapshotWhenRemoveEnabled : 
triggerSnapshotWhenStopEnabled;
+  }
+
+  void setRemoving() {
+    this.isRemoving = true;
+  }
+
   private long getLastAppliedIndex() {
     return appliedIndex.get();
   }

Reply via email to