Repository: mina-sshd
Updated Branches:
  refs/heads/master 644649975 -> a4bb50233


[SSHD-835] Further clarified documentation regarding usage of 
CloseableExecutorService(s)


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

Branch: refs/heads/master
Commit: a4bb502333ea96755e79fef850235b26d6aafb81
Parents: 1e29158
Author: Goldstein Lyor <[email protected]>
Authored: Thu Jul 26 08:00:58 2018 +0300
Committer: Goldstein Lyor <[email protected]>
Committed: Thu Jul 26 08:04:30 2018 +0300

----------------------------------------------------------------------
 README.md | 37 +++++++++++++++++++++++++++++--------
 1 file changed, 29 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a4bb5023/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index b718b16..a44b48d 100644
--- a/README.md
+++ b/README.md
@@ -409,28 +409,49 @@ be tailored to present different views for different 
clients
 ## `ExecutorService`-s
 
 The framework requires from time to time spawning some threads in order to 
function correctly - e.g., commands, SFTP subsystem,
-port forwarding (among others) require such support. By default, the framework 
will allocate an 
[ExecutorService](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html)
 for each specific purpose and then shut it down when the module has completed 
its work - e.g., session
-was closed. Note that SSHD uses the `CloseableExecutorService` interface 
instead of the usual `ExecutorService` in order to provide graceful shutdown.
-Users may provide their own `CloseableExecutorService`(s) instead of the 
internally auto-allocated ones - e.g., in
-order to control the max. spawned threads, stack size, track threads, etc... 
but they can leverage the `ThreadUtils.ThreadPoolExecutor` implementation which 
should cover most use cases.
-If a single executor is shared between several services, it needs to be 
wrapped with the `ThreadUtils.noClose(executor)` method.
+port forwarding (among others) require such support. By default, the framework 
will allocate an 
[ExecutorService](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html)
+for each specific purpose and then shut it down when the module has completed 
its work - e.g., session was closed. Note that
+SSHD uses the `CloseableExecutorService` interface instead of the usual 
`ExecutorService` in order to provide graceful shutdown.
+Users may provide their own `CloseableExecutorService`(s) instead of the 
internally auto-allocated ones - e.g., in order to
+control the max. spawned threads, stack size, track threads, etc... but they 
can leverage the `SshThreadPoolExecutor` implementation
+which should cover most use cases.
+
+Users who want to provide their own `ExecutorService` and not use 
`SshThreadPoolExecutor` should wrap it as a `NoCloseExecutor`
+and take care of shutting it down when SSHD is done with (provided, of course, 
that the user's own code does not need it to
+remain active afterwards...).
 
 ```java
 
     /*
-     * An example for SFTP - there are other such locations. By default,
-     * the SftpSubsystem implementation creates a single-threaded executor
+     * An example user-provided executor service for SFTP - there are other 
such locations.
+     * By default, the SftpSubsystem implementation creates a single-threaded 
executor
      * for each session, uses it to spawn the SFTP command handler and shuts
      * it down when the command is destroyed
      */
     SftpSubsystemFactory factory = new SftpSubsystemFactory.Builder()
-        .withExecutorService(ThreadUtils.noClose(mySuperDuperExecutorService))
+        .withExecutorService(new NoCloseExecutor(mySuperDuperExecutorService))
         .build();
     SshServer sshd = SshServer.setupDefaultServer();
     
sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(factory));
 
 ```
 
+If a single `CloseableExecutorService` is shared between several services, it 
needs to be wrapped with the
+`ThreadUtils.noClose(executor)` method.
+
+```java
+    CloseableExecutorService sharedService = ...obtain/create an instance...;
+
+    SftpSubsystemFactory factory = new SftpSubsystemFactory.Builder()
+        .withExecutorService(ThreadUtils.noClose(sharedService))
+        .build();
+
+   ChannelAgentForwarding forward = new 
ChannelAgentForwarding(ThreadUtils.noClose(sharedService));
+```
+
+**Note:** Do not share the instance returned by `ThreadUtils.noClose` between 
services as it interferes with
+the graceful closing mechanism. Use a new wrapper instance for each service.
+
 ## Remote command execution
 
 All command execution - be it shell or single command - boils down to a 
`Command` instance being created, initialized and then

Reply via email to