You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ratis.apache.org by sh...@apache.org on 2020/06/24 08:29:39 UTC
[incubator-ratis] branch master updated: RATIS-982. Fix
RaftServerImpl illegal transition from RUNNING to RUNNING (#134)
This is an automated email from the ASF dual-hosted git repository.
shashikant 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 b2d367f RATIS-982. Fix RaftServerImpl illegal transition from RUNNING to RUNNING (#134)
b2d367f is described below
commit b2d367fa9a9313c7bae3ca5a02c652a8804b97e1
Author: runzhiwang <51...@users.noreply.github.com>
AuthorDate: Wed Jun 24 16:29:29 2020 +0800
RATIS-982. Fix RaftServerImpl illegal transition from RUNNING to RUNNING (#134)
---
.../org/apache/ratis/server/impl/RaftServerImpl.java | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 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 c5d5b48..c4f9ec2 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
@@ -48,6 +48,7 @@ import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -94,6 +95,13 @@ public class RaftServerImpl implements RaftServerProtocol, RaftServerAsynchronou
private AtomicReference<TermIndex> inProgressInstallSnapshotRequest;
+ // To avoid append entry before complete start() method
+ // For example, if thread1 start(), but before thread1 startAsFollower(), thread2 receive append entry
+ // request, and change state to RUNNING by lifeCycle.compareAndTransition(STARTING, RUNNING),
+ // then thread1 execute lifeCycle.transition(RUNNING) in startAsFollower(),
+ // So happens IllegalStateException: ILLEGAL TRANSITION: RUNNING -> RUNNING,
+ private AtomicBoolean startComplete;
+
RaftServerImpl(RaftGroup group, StateMachine stateMachine, RaftServerProxy proxy) throws IOException {
final RaftPeerId id = proxy.getId();
LOG.info("{}: new RaftServerImpl for {} with {}", id, group, stateMachine);
@@ -118,6 +126,8 @@ public class RaftServerImpl implements RaftServerProtocol, RaftServerAsynchronou
this.jmxAdapter = new RaftServerJmxAdapter();
this.leaderElectionMetrics = LeaderElectionMetrics.getLeaderElectionMetrics(this);
this.raftServerMetrics = RaftServerMetrics.getRaftServerMetrics(this);
+
+ this.startComplete = new AtomicBoolean(false);
}
private RetryCache initRetryCache(RaftProperties prop) {
@@ -192,6 +202,7 @@ public class RaftServerImpl implements RaftServerProtocol, RaftServerAsynchronou
registerMBean(getId(), getMemberId().getGroupId(), jmxAdapter, jmxAdapter);
state.start();
+ startComplete.compareAndSet(false, true);
return true;
}
@@ -946,11 +957,9 @@ public class RaftServerImpl implements RaftServerProtocol, RaftServerAsynchronou
CodeInjectionForTesting.execute(APPEND_ENTRIES, getId(),
leaderId, leaderTerm, previous, leaderCommit, initializing, entries);
- final LifeCycle.State currentState = assertLifeCycleState(LifeCycle.States.STARTING_OR_RUNNING);
- if (currentState == STARTING) {
- if (role.getCurrentRole() == null) {
- throw new ServerNotReadyException(getMemberId() + ": The server role is not yet initialized.");
- }
+ assertLifeCycleState(LifeCycle.States.STARTING_OR_RUNNING);
+ if (!startComplete.get()) {
+ throw new ServerNotReadyException(getMemberId() + ": The server role is not yet initialized.");
}
assertGroup(leaderId, leaderGroupId);