public abstract class ConcurrentServerRunner<T extends Client> extends ContextAwareBase implements java.lang.Runnable, ServerRunner<T>
ServerRunner.
An instance of this object is created with a ServerListener and
an Executor. On invocation of the #start() method, it
passes itself to the given Executor and returns immediately. On
invocation of its run() method by the Executor it begins
accepting client connections via its ServerListener. As each
new Client is accepted, the client is configured with the
runner's LoggingContext and is then passed to the Executor for concurrent execution of the client's service loop.
On invocation of the stop() method, the runner closes the listener
and each of the connected clients (by invoking Client.close()
effectively interrupting any blocked I/O calls and causing these concurrent
subtasks to exit gracefully). This ensures that before the stop()
method returns (1) all I/O resources have been released and (2) all
of the threads of the Executor are idle.
| Modifier and Type | Class and Description |
|---|---|
private class |
ConcurrentServerRunner.ClientWrapper
A wrapper for a
Client responsible for ensuring that client
tracking is performed properly. |
| Modifier and Type | Field and Description |
|---|---|
private java.util.Collection<T> |
clients |
private java.util.concurrent.locks.Lock |
clientsLock |
private java.util.concurrent.Executor |
executor |
private ServerListener<T> |
listener |
private boolean |
running |
context| Constructor and Description |
|---|
ConcurrentServerRunner(ServerListener<T> listener,
java.util.concurrent.Executor executor)
Constructs a new server runner.
|
| Modifier and Type | Method and Description |
|---|---|
void |
accept(ClientVisitor<T> visitor)
Presents each connected client to the given visitor.
|
private void |
addClient(T client)
Adds a client to the collection of those being tracked by the server.
|
protected abstract boolean |
configureClient(T client)
Configures a connected client.
|
private java.util.Collection<T> |
copyClients()
Creates a copy of the collection of all clients that are presently
being tracked by the server.
|
boolean |
isRunning()
Gets a flag indicating whether the server is currently running.
|
private void |
removeClient(T client)
Removes a client from the collection of those being tracked by the server.
|
void |
run() |
protected void |
setRunning(boolean running) |
void |
stop()
Stops execution of the runner.
|
addError, addError, addInfo, addInfo, addStatus, addWarn, addWarn, getContext, getDeclaredOrigin, getStatusManager, setContextclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitaddError, addError, addInfo, addInfo, addStatus, addWarn, addWarn, getContext, setContextprivate final java.util.concurrent.locks.Lock clientsLock
private final ServerListener<T extends Client> listener
private final java.util.concurrent.Executor executor
private boolean running
public ConcurrentServerRunner(ServerListener<T> listener, java.util.concurrent.Executor executor)
listener - the listener from which the server will accept new
clientsexecutor - a executor that will facilitate execution of the
listening and client-handling tasks; while any Executor
is allowed here, outside of unit testing the only reasonable choice
is a bounded thread pool of some kind.public boolean isRunning()
isRunning in interface ServerRunner<T extends Client>protected void setRunning(boolean running)
public void stop()
throws java.io.IOException
This method must cause all I/O and thread resources associated with the runner to be released. If the receiver has not been started, this method must have no effect.
stop in interface ServerRunner<T extends Client>java.io.IOExceptionpublic void accept(ClientVisitor<T> visitor)
accept in interface ServerRunner<T extends Client>visitor - the subject visitorprivate java.util.Collection<T> copyClients()
public void run()
run in interface java.lang.Runnableprotected abstract boolean configureClient(T client)
A subclass implements this method to perform any necessary configuration
of the client object before its Runnable.run() method is invoked.
client - the subject clienttrue if configuration was successful; if the return
value is false the client connection will be droppedprivate void addClient(T client)
client - the client to addprivate void removeClient(T client)
client - the client to remote