You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2016/01/24 07:23:53 UTC

mina-sshd git commit: Add a configurable wait time for closing or stopping

Repository: mina-sshd
Updated Branches:
  refs/heads/master 6a8253d62 -> d8c861f2d


Add a configurable wait time for closing or stopping


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/d8c861f2
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/d8c861f2
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/d8c861f2

Branch: refs/heads/master
Commit: d8c861f2d282648ea490cd2bda580cc619205a30
Parents: 6a8253d
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Sun Jan 24 08:23:42 2016 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Sun Jan 24 08:23:42 2016 +0200

----------------------------------------------------------------------
 .../java/org/apache/sshd/client/SshClient.java  | 15 ++++++++++--
 .../org/apache/sshd/common/FactoryManager.java  | 12 ++++++++++
 .../apache/sshd/common/io/nio2/Nio2Service.java | 20 +++++++++++++---
 .../common/util/closeable/CloseableUtils.java   | 25 +++++++++++++++++++-
 .../java/org/apache/sshd/server/SshServer.java  |  7 +++++-
 5 files changed, 72 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d8c861f2/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
index 8c31468..92bfbba 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
@@ -30,6 +30,7 @@ import java.io.StreamCorruptedException;
 import java.io.StringWriter;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
+import java.net.SocketTimeoutException;
 import java.nio.file.Files;
 import java.nio.file.LinkOption;
 import java.nio.file.Path;
@@ -396,9 +397,19 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
 
     public void stop() {
         try {
-            close(true).await();    // TODO use verify + configurable timeout
+            long maxWait = PropertyResolverUtils.getLongProperty(this, STOP_WAIT_TIME, DEFAULT_STOP_WAIT_TIME);
+            boolean successful = close(true).await(maxWait);
+            if (!successful) {
+                throw new SocketTimeoutException("Failed to receive closure confirmation within " + maxWait + " millis");
+            }
         } catch (IOException e) {
-            log.debug("Exception caught while stopping client", e);
+            if (log.isDebugEnabled()) {
+                log.debug(e.getClass().getSimpleName() + " while stopping client: " + e.getMessage());
+            }
+
+            if (log.isTraceEnabled()) {
+                log.trace("Stop exception details", e);
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d8c861f2/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
index eadc6cb..9a3a65c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
@@ -144,6 +144,18 @@ public interface FactoryManager extends KexFactoryManager, SessionListenerManage
     long DEFAULT_CHANNEL_CLOSE_TIMEOUT = TimeUnit.SECONDS.toMillis(5L);
 
     /**
+     * Timeout (milliseconds) to wait for client / server stop request
+     * if immediate stop requested.
+     * @see #DEFAULT_STOP_WAIT_TIME
+     */
+    String STOP_WAIT_TIME = "stop-wait-time";
+
+    /**
+     * Default value for {@link #STOP_WAIT_TIME} if none specified
+     */
+    long DEFAULT_STOP_WAIT_TIME = TimeUnit.MINUTES.toMillis(1L);
+
+    /**
      * Socket backlog.
      * See {@link java.nio.channels.AsynchronousServerSocketChannel#bind(java.net.SocketAddress, int)}
      */

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d8c861f2/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java
index ba1494c..1df3731 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java
@@ -20,6 +20,7 @@ package org.apache.sshd.common.io.nio2;
 
 import java.io.IOException;
 import java.net.SocketOption;
+import java.net.SocketTimeoutException;
 import java.nio.channels.AsynchronousChannelGroup;
 import java.nio.channels.NetworkChannel;
 import java.util.Collection;
@@ -37,6 +38,7 @@ import org.apache.sshd.common.io.IoSession;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.closeable.AbstractInnerCloseable;
+import org.apache.sshd.common.util.closeable.CloseableUtils;
 
 /**
  */
@@ -48,7 +50,9 @@ public abstract class Nio2Service extends AbstractInnerCloseable implements IoSe
     protected final AsynchronousChannelGroup group;
 
     protected Nio2Service(FactoryManager manager, IoHandler handler, AsynchronousChannelGroup group) {
-        log.trace("Creating {}", getClass().getSimpleName());
+        if (log.isTraceEnabled()) {
+            log.trace("Creating {}", getClass().getSimpleName());
+        }
         this.manager = ValidateUtils.checkNotNull(manager, "No factory manager provided");
         this.handler = ValidateUtils.checkNotNull(handler, "No I/O handler provided");
         this.group = ValidateUtils.checkNotNull(group, "No async. channel group provided");
@@ -57,9 +61,19 @@ public abstract class Nio2Service extends AbstractInnerCloseable implements IoSe
 
     public void dispose() {
         try {
-            close(true).await();    // TODO use verify+(configurable) timeout
+            long maxWait = CloseableUtils.getMaxCloseWaitTime(manager);
+            boolean successful = close(true).await(maxWait);
+            if (!successful) {
+                throw new SocketTimeoutException("Failed to receive closure confirmation within " + maxWait + " millis");
+            }
         } catch (IOException e) {
-            log.debug("Exception caught while closing", e);
+            if (log.isDebugEnabled()) {
+                log.debug(e.getClass().getSimpleName() + " while stopping service: " + e.getMessage());
+            }
+
+            if (log.isTraceEnabled()) {
+                log.trace("Stop exception details", e);
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d8c861f2/sshd-core/src/main/java/org/apache/sshd/common/util/closeable/CloseableUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/closeable/CloseableUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/closeable/CloseableUtils.java
index 172ce99..e0223c1 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/closeable/CloseableUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/closeable/CloseableUtils.java
@@ -19,8 +19,12 @@
 package org.apache.sshd.common.util.closeable;
 
 import java.io.IOException;
+import java.net.SocketTimeoutException;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.sshd.common.Closeable;
+import org.apache.sshd.common.PropertyResolver;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.future.CloseFuture;
 import org.apache.sshd.common.future.DefaultCloseFuture;
 
@@ -30,6 +34,17 @@ import org.apache.sshd.common.future.DefaultCloseFuture;
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public final class CloseableUtils {
+    /**
+     * Timeout (milliseconds) for waiting on a {@link CloseFuture} to successfully
+     * complete its action.
+     * @see #DEFAULT_CLOSE_WAIT_TIMEOUT
+     */
+    public static final String CLOSE_WAIT_TIMEOUT = "sshd-close-wait-time";
+
+    /**
+     * Default value for {@link #CLOSE_WAIT_TIMEOUT} if none specified
+     */
+    public static final long DEFAULT_CLOSE_WAIT_TIMEOUT = TimeUnit.SECONDS.toMillis(15L);
 
     /**
      * Private Constructor
@@ -38,6 +53,10 @@ public final class CloseableUtils {
         throw new UnsupportedOperationException("No instance allowed");
     }
 
+    public static long getMaxCloseWaitTime(PropertyResolver resolver) {
+        return (resolver == null) ? DEFAULT_CLOSE_WAIT_TIMEOUT : PropertyResolverUtils.getLongProperty(resolver, CLOSE_WAIT_TIMEOUT, DEFAULT_CLOSE_WAIT_TIMEOUT);
+    }
+
     // TODO once JDK 8+ becomes the minimum for this project, make it a static method in the Closeable interface
     public static void close(Closeable closeable) throws IOException {
         if (closeable == null) {
@@ -46,7 +65,11 @@ public final class CloseableUtils {
 
         if ((!closeable.isClosed()) && (!closeable.isClosing())) {
             CloseFuture future = closeable.close(true);
-            future.await();  // TODO use verify + configurable timeout
+            long maxWait = (closeable instanceof PropertyResolver) ? getMaxCloseWaitTime((PropertyResolver) closeable) : DEFAULT_CLOSE_WAIT_TIMEOUT;
+            boolean successful = future.await(maxWait);
+            if (!successful) {
+                throw new SocketTimeoutException("Failed to receive closure confirmation within " + maxWait + " millis");
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d8c861f2/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
index 2c63f26..fa573fb 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
@@ -22,6 +22,7 @@ import java.io.File;
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.net.SocketTimeoutException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -316,7 +317,11 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
     }
 
     public void stop(boolean immediately) throws IOException {
-        close(immediately).await(); // TODO use verify + configurable timeout
+        long maxWait = immediately ? PropertyResolverUtils.getLongProperty(this, STOP_WAIT_TIME, DEFAULT_STOP_WAIT_TIME) : Long.MAX_VALUE;
+        boolean successful = close(immediately).await(maxWait);
+        if (!successful) {
+            throw new SocketTimeoutException("Failed to receive closure confirmation within " + maxWait + " millis");
+        }
     }
 
     public void open() throws IOException {