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 {