RATIS-2036. Avoid trigger snapshot when removing raftGroup (#1055)
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 565e881..7419ca0 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 @@
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 23cab70..0ea3746 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
@@ -461,6 +461,7 @@
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 b01270d..fbd7f01 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 @@
private final boolean triggerSnapshotWhenStopEnabled;
+ private final boolean triggerSnapshotWhenRemoveEnabled;
+
private final Long autoSnapshotThreshold;
private final boolean purgeUptoSnapshotIndex;
@@ -91,6 +93,8 @@
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 @@
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);
@@ -327,12 +332,33 @@
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();
}