This is an automated email from the ASF dual-hosted git repository.
szetszwo 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 499f1d8 RATIS-578. Illegal State transition in LeaderElection.
499f1d8 is described below
commit 499f1d83707a88482c9e1341dd841200cc7e7d88
Author: Tsz Wo Nicholas Sze <[email protected]>
AuthorDate: Fri Aug 2 12:56:10 2019 -0700
RATIS-578. Illegal State transition in LeaderElection.
---
.../apache/ratis/server/impl/LeaderElection.java | 10 ++--
.../impl/RaftStateMachineExceptionTests.java | 53 ++++++++++------------
2 files changed, 27 insertions(+), 36 deletions(-)
diff --git
a/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderElection.java
b/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderElection.java
index b0b3113..8a8dc07 100644
---
a/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderElection.java
+++
b/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderElection.java
@@ -110,14 +110,16 @@ class LeaderElection implements Runnable {
private final RaftServerImpl server;
LeaderElection(RaftServerImpl server) {
- this.name = server.getId() + ":" + server.getGroupId() + ":" +
getClass().getSimpleName() + COUNT.incrementAndGet();
+ this.name = server.getMemberId() + ":" + getClass().getSimpleName() +
COUNT.incrementAndGet();
this.lifeCycle = new LifeCycle(this);
this.daemon = new Daemon(this);
this.server = server;
}
void start() {
- lifeCycle.startAndTransition(daemon::start);
+ lifeCycle.transition(LifeCycle.State.STARTING);
+ lifeCycle.transition(LifeCycle.State.RUNNING);
+ daemon.start();
}
void shutdown() {
@@ -128,10 +130,6 @@ class LeaderElection implements Runnable {
public void run() {
try {
askForVotes();
- } catch (InterruptedException e) {
- // the leader election thread is interrupted. The peer may already step
- // down to a follower. The leader election should skip.
- LOG.info("{} thread is interrupted gracefully; server={}", this, server);
} catch(Throwable e) {
final LifeCycle.State state = lifeCycle.getCurrentState();
final String message = "Failed " + this + ", state=" + state;
diff --git
a/ratis-server/src/test/java/org/apache/ratis/server/impl/RaftStateMachineExceptionTests.java
b/ratis-server/src/test/java/org/apache/ratis/server/impl/RaftStateMachineExceptionTests.java
index 7e6b376..f89699e 100644
---
a/ratis-server/src/test/java/org/apache/ratis/server/impl/RaftStateMachineExceptionTests.java
+++
b/ratis-server/src/test/java/org/apache/ratis/server/impl/RaftStateMachineExceptionTests.java
@@ -71,14 +71,17 @@ public abstract class
RaftStateMachineExceptionTests<CLUSTER extends MiniRaftClu
}
}
+ {
+ final RaftProperties prop = getProperties();
+ prop.setClass(MiniRaftCluster.STATEMACHINE_CLASS_KEY,
StateMachineWithException.class, StateMachine.class);
+ }
+
@Test
public void testHandleStateMachineException() throws Exception {
- final RaftProperties prop = getProperties();
- prop.setClass(MiniRaftCluster.STATEMACHINE_CLASS_KEY,
- StateMachineWithException.class, StateMachine.class);
- final MiniRaftCluster cluster = newCluster(3);
- cluster.start();
+ runWithNewCluster(3, this::runTestHandleStateMachineException);
+ }
+ private void runTestHandleStateMachineException(CLUSTER cluster) throws
Exception {
RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
try(final RaftClient client = cluster.createClient(leaderId)) {
@@ -93,12 +96,10 @@ public abstract class
RaftStateMachineExceptionTests<CLUSTER extends MiniRaftClu
@Test
public void testRetryOnStateMachineException() throws Exception {
- final RaftProperties prop = getProperties();
- prop.setClass(MiniRaftCluster.STATEMACHINE_CLASS_KEY,
- StateMachineWithException.class, StateMachine.class);
- final MiniRaftCluster cluster = newCluster(3);
- cluster.start();
+ runWithNewCluster(3, this::runTestRetryOnStateMachineException);
+ }
+ private void runTestRetryOnStateMachineException(CLUSTER cluster) throws
Exception {
RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
cluster.getLeaderAndSendFirstMessage(true);
@@ -141,38 +142,30 @@ public abstract class
RaftStateMachineExceptionTests<CLUSTER extends MiniRaftClu
@Test
public void testRetryOnExceptionDuringReplication() throws Exception {
- final RaftProperties prop = getProperties();
- prop.setClass(MiniRaftCluster.STATEMACHINE_CLASS_KEY,
- StateMachineWithException.class, StateMachine.class);
- final MiniRaftCluster cluster = newCluster(3);
- cluster.start();
- RaftTestUtil.waitForLeader(cluster);
- RaftServerImpl leader = cluster.getLeader();
- RaftPeerId leaderId = leader.getId();
+ runWithNewCluster(3, this::runTestRetryOnExceptionDuringReplication);
+ }
+
+ private void runTestRetryOnExceptionDuringReplication(CLUSTER cluster)
throws Exception {
+ final RaftServerImpl oldLeader = RaftTestUtil.waitForLeader(cluster);
cluster.getLeaderAndSendFirstMessage(true);
// turn on the preAppend failure switch
failPreAppend = true;
- final RaftClient client = cluster.createClient(leaderId);
+ final RaftClient client = cluster.createClient(oldLeader.getId());
final RaftClientRpc rpc = client.getClientRpc();
final long callId = 999;
- RaftClientRequest r = cluster.newRaftClientRequest(client.getId(),
leaderId,
- callId, new RaftTestUtil.SimpleMessage("message"));
+ final SimpleMessage message = new SimpleMessage("message");
+ RaftClientRequest r = cluster.newRaftClientRequest(client.getId(),
oldLeader.getId(), callId, message);
RaftClientReply reply = rpc.sendRequest(r);
Objects.requireNonNull(reply.getStateMachineException());
- RetryCache.CacheEntry oldEntry = RaftServerTestUtil.getRetryEntry(
- leader, client.getId(), callId);
+ final RetryCache.CacheEntry oldEntry =
RaftServerTestUtil.getRetryEntry(oldLeader, client.getId(), callId);
Assert.assertNotNull(oldEntry);
Assert.assertTrue(RaftServerTestUtil.isRetryCacheEntryFailed(oldEntry));
- // At this point of time the old leader would have stepped down. wait for
- // leader election to complete
- RaftTestUtil.waitForLeader(cluster);
- leader = cluster.getLeader();
- leaderId = leader.getId();
+ // At this point of time the old leader would have stepped down. wait for
leader election to complete
+ final RaftServerImpl leader = RaftTestUtil.waitForLeader(cluster);
// retry
- r = cluster.newRaftClientRequest(client.getId(), leaderId,
- callId, new RaftTestUtil.SimpleMessage("message"));
+ r = cluster.newRaftClientRequest(client.getId(), leader.getId(), callId,
message);
reply = rpc.sendRequest(r);
Objects.requireNonNull(reply.getStateMachineException());