Repository: incubator-ratis
Updated Branches:
  refs/heads/master 83e5d99e5 -> f7f97e050


RATIS-175. RaftServerProxy should close server rpc in case instance creation 
fails.  Contributed by Lokesh Jain


Project: http://git-wip-us.apache.org/repos/asf/incubator-ratis/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ratis/commit/f7f97e05
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ratis/tree/f7f97e05
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ratis/diff/f7f97e05

Branch: refs/heads/master
Commit: f7f97e0506447f5d9f6be100e91017871af9762b
Parents: 83e5d99
Author: Tsz-Wo Nicholas Sze <[email protected]>
Authored: Sat Dec 23 01:01:38 2017 +0800
Committer: Tsz-Wo Nicholas Sze <[email protected]>
Committed: Sat Dec 23 01:01:38 2017 +0800

----------------------------------------------------------------------
 .../ratis/grpc/TestRaftServerWithGrpc.java      | 56 ++++++++++++++++++++
 .../ratis/server/impl/RaftServerProxy.java      | 12 ++++-
 .../ratis/server/impl/RaftServerTestUtil.java   | 12 ++++-
 3 files changed, 78 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/f7f97e05/ratis-grpc/src/test/java/org/apache/ratis/grpc/TestRaftServerWithGrpc.java
----------------------------------------------------------------------
diff --git 
a/ratis-grpc/src/test/java/org/apache/ratis/grpc/TestRaftServerWithGrpc.java 
b/ratis-grpc/src/test/java/org/apache/ratis/grpc/TestRaftServerWithGrpc.java
new file mode 100644
index 0000000..dcdcee4
--- /dev/null
+++ b/ratis-grpc/src/test/java/org/apache/ratis/grpc/TestRaftServerWithGrpc.java
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ratis.grpc;
+
+import org.apache.ratis.RaftTestUtil;
+import org.apache.ratis.conf.RaftProperties;
+import org.apache.ratis.protocol.RaftPeerId;
+import org.apache.ratis.server.impl.RaftServerTestUtil;
+import org.junit.Test;
+
+public class TestRaftServerWithGrpc {
+
+  @Test
+  public void testServerRestartOnException() throws Exception {
+    RaftProperties properties = new RaftProperties();
+    final MiniRaftClusterWithGRpc cluster
+        = MiniRaftClusterWithGRpc.FACTORY.newCluster(1, properties);
+    cluster.start();
+    RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
+    GrpcConfigKeys.Server.setPort(properties, 
cluster.getLeader().getServerRpc().getInetSocketAddress().getPort());
+    // Create a raft server proxy with server rpc bound to a different address
+    // compared to leader. This helps in locking the raft storage directory to
+    // be used by next raft server proxy instance.
+    RaftServerTestUtil.getRaftServerProxy(leaderId, 
cluster.getLeader().getStateMachine(), cluster.getGroup(),
+        new RaftProperties(), null);
+    // Close the server rpc for leader so that new raft server can be bound to 
it.
+    cluster.getLeader().getServerRpc().close();
+    try {
+      // Create a raft server proxy with server rpc bound to same address as
+      // the leader. This step would fail as the raft storage has been locked 
by
+      // the raft server proxy created earlier. Raft server proxy should close
+      // the rpc server on failure.
+      RaftServerTestUtil
+          .getRaftServerProxy(leaderId, cluster.getLeader().getStateMachine(), 
cluster.getGroup(),
+              properties, null);
+    } catch (Exception e) {
+    }
+    // Try to start a raft server rpc at the leader address.
+    
cluster.getServer(leaderId).getFactory().newRaftServerRpc(cluster.getServer(leaderId));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/f7f97e05/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java
----------------------------------------------------------------------
diff --git 
a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java 
b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java
index 7f7a2bf..27483ec 100644
--- 
a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java
+++ 
b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java
@@ -63,7 +63,17 @@ public class RaftServerProxy implements RaftServer {
 
     this.serverRpc = factory.newRaftServerRpc(this);
     this.id = id != null? id: RaftPeerId.valueOf(getIdStringFrom(serverRpc));
-    this.impl = CompletableFuture.completedFuture(initImpl(group));
+    try {
+      this.impl = CompletableFuture.completedFuture(initImpl(group));
+    } catch (IOException ioe) {
+      try {
+        serverRpc.close();
+      } catch (IOException closeIoe) {
+        ioe.addSuppressed(closeIoe);
+      } finally {
+        throw ioe;
+      }
+    }
   }
 
   private RaftServerImpl initImpl(RaftGroup group) throws IOException {

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/f7f97e05/ratis-server/src/test/java/org/apache/ratis/server/impl/RaftServerTestUtil.java
----------------------------------------------------------------------
diff --git 
a/ratis-server/src/test/java/org/apache/ratis/server/impl/RaftServerTestUtil.java
 
b/ratis-server/src/test/java/org/apache/ratis/server/impl/RaftServerTestUtil.java
index 909685f..686a008 100644
--- 
a/ratis-server/src/test/java/org/apache/ratis/server/impl/RaftServerTestUtil.java
+++ 
b/ratis-server/src/test/java/org/apache/ratis/server/impl/RaftServerTestUtil.java
@@ -18,14 +18,19 @@
 package org.apache.ratis.server.impl;
 
 import org.apache.ratis.MiniRaftCluster;
-import org.apache.ratis.RaftTestUtil;
+import org.apache.ratis.conf.Parameters;
+import org.apache.ratis.conf.RaftProperties;
 import org.apache.ratis.protocol.ClientId;
+import org.apache.ratis.protocol.RaftGroup;
 import org.apache.ratis.protocol.RaftPeer;
+import org.apache.ratis.protocol.RaftPeerId;
+import org.apache.ratis.statemachine.StateMachine;
 import org.apache.ratis.util.JavaUtils;
 import org.junit.Assert;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.IOException;
 import java.util.Collection;
 
 public class RaftServerTestUtil {
@@ -79,4 +84,9 @@ public class RaftServerTestUtil {
   public static boolean isRetryCacheEntryFailed(RetryCache.CacheEntry entry) {
     return entry.isFailed();
   }
+
+  public static RaftServerProxy getRaftServerProxy(RaftPeerId id, StateMachine 
stateMachine,
+      RaftGroup group, RaftProperties properties, Parameters parameters) 
throws IOException {
+    return new RaftServerProxy(id, stateMachine, group, properties, 
parameters);
+  }
 }

Reply via email to