Class ServerSocketAccept
- java.lang.Object
-
- org.obrel.core.RelatedObject
-
- de.esoco.coroutine.CoroutineStep<I,O>
-
- de.esoco.coroutine.step.nio.AsynchronousChannelStep<java.lang.Void,java.lang.Void>
-
- de.esoco.coroutine.step.nio.ServerSocketAccept
-
- All Implemented Interfaces:
de.esoco.lib.property.Fluent<CoroutineStep<java.lang.Void,java.lang.Void>>,org.obrel.core.FluentRelatable<CoroutineStep<java.lang.Void,java.lang.Void>>,org.obrel.core.Relatable
public class ServerSocketAccept extends AsynchronousChannelStep<java.lang.Void,java.lang.Void>
A coroutine step for servers that listens to network request through an instance ofAsynchronousServerSocketChannel. The step will suspend execution until a request is accepted and then spawn another coroutine for the handling of the request. The handling coroutine will receive theAsynchronousSocketChannelfor the communication with the client. It could then store the channel asAsynchronousSocketStep.SOCKET_CHANNELand process the request withSocketReceiveandSocketSendsteps.After the request handling coroutine has been spawned this step will resume execution of it's own coroutine. A typical server accept loop therefore needs to be implemented in that coroutine, e.g. inside a conditional
Loopstep. Handling coroutines will run in parallel in separate continuations but in the same scope. Interdependencies between the main coroutine and the request handling should be avoided to prevent the risk of deadlocks.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description protected static classServerSocketAccept.AcceptCallbackACompletionHandlerimplementation that receives the result of an asynchronous accept and processes the request with an asynchronous coroutine execution.-
Nested classes/interfaces inherited from class de.esoco.coroutine.step.nio.AsynchronousChannelStep
AsynchronousChannelStep.ChannelCallback<V,C extends java.nio.channels.AsynchronousChannel>, AsynchronousChannelStep.ChannelOperation<C extends java.nio.channels.AsynchronousChannel>
-
-
Field Summary
Fields Modifier and Type Field Description static org.obrel.core.RelationType<java.nio.channels.AsynchronousServerSocketChannel>SERVER_SOCKET_CHANNELState: anAsynchronousServerSocketChannelthat has been openened and connected by an asynchronous execution.-
Fields inherited from class de.esoco.coroutine.step.nio.AsynchronousChannelStep
CHANNEL_GROUP
-
-
Constructor Summary
Constructors Constructor Description ServerSocketAccept(java.util.function.Function<Continuation<?>,java.net.SocketAddress> getSocketAddress, Coroutine<java.nio.channels.AsynchronousSocketChannel,?> requestHandler)Creates a new instance that accepts a single server request and processes it asynchronously in a coroutine.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static ServerSocketAcceptacceptRequestOn(java.util.function.Function<Continuation<?>,java.net.SocketAddress> getSocketAddress, Coroutine<java.nio.channels.AsynchronousSocketChannel,?> requestHandler)Accepts an incoming request on the given socket address and then handles it by executing the given coroutine with the client socket channel as it's input.protected java.lang.Voidexecute(java.lang.Void input, Continuation<?> continuation)This method must be implemented by subclasses to provide the actual functionality of this step.protected java.nio.channels.AsynchronousServerSocketChannelgetServerSocketChannel(Continuation<?> continuation)Returns the channel to be used by this step.protected java.net.SocketAddressgetSocketAddress(Continuation<?> continuation)Returns the address of the socket to connect to.protected java.util.function.Function<Continuation<?>,java.net.SocketAddress>getSocketAddressFactory()Returns the socket address factory of this step.voidrunAsync(java.util.concurrent.CompletableFuture<java.lang.Void> previousExecution, CoroutineStep<java.lang.Void,?> nextStep, Continuation<?> continuation)Runs this execution step asynchronously as a continuation of a previous code execution in aCompletableFutureand proceeds to the next step afterwards.-
Methods inherited from class de.esoco.coroutine.step.nio.AsynchronousChannelStep
getChannelGroup
-
Methods inherited from class de.esoco.coroutine.CoroutineStep
runBlocking, terminateCoroutine, toString
-
Methods inherited from class org.obrel.core.RelatedObject
deleteRelation, get, getRelation, getRelations, notifyRelationListeners, readRelations, relationsEqual, relationsHashCode, relationsString, set, set, transform, writeRelations
-
-
-
-
Constructor Detail
-
ServerSocketAccept
public ServerSocketAccept(java.util.function.Function<Continuation<?>,java.net.SocketAddress> getSocketAddress, Coroutine<java.nio.channels.AsynchronousSocketChannel,?> requestHandler)
Creates a new instance that accepts a single server request and processes it asynchronously in a coroutine. The server socket is bound to the local socket with the address provided by the given factory. The factory may return NULL if the step should connect to a channel that is stored in a state relation with the typeSERVER_SOCKET_CHANNEL.- Parameters:
getSocketAddress- A function that provides the socket address to connect to from the current continuationrequestHandler- A coroutine that processes a single server request
-
-
Method Detail
-
acceptRequestOn
public static ServerSocketAccept acceptRequestOn(java.util.function.Function<Continuation<?>,java.net.SocketAddress> getSocketAddress, Coroutine<java.nio.channels.AsynchronousSocketChannel,?> requestHandler)
Accepts an incoming request on the given socket address and then handles it by executing the given coroutine with the client socket channel as it's input.- Parameters:
getSocketAddress- A function that produces the address of the local address to accept the request fromrequestHandler- The coroutine to process the next request with- Returns:
- The new step
-
runAsync
public void runAsync(java.util.concurrent.CompletableFuture<java.lang.Void> previousExecution, CoroutineStep<java.lang.Void,?> nextStep, Continuation<?> continuation)Runs this execution step asynchronously as a continuation of a previous code execution in aCompletableFutureand proceeds to the next step afterwards.Subclasses that need to suspend the invocation of the next step until some condition is met (e.g. sending or receiving data has finished) need to override this method and create a
Suspensionby invokingContinuation.suspend(CoroutineStep, CoroutineStep)on the next step. If the condition that caused the suspension resolves the coroutine execution can be resumed by callingSuspension.resume(Object).Subclasses that override this method also need to handle errors by terminating any further execution (i.e. not resuming a suspension if such exists) and forwarding the causing exception to
Continuation.fail(Throwable).- Overrides:
runAsyncin classCoroutineStep<java.lang.Void,java.lang.Void>- Parameters:
previousExecution- The future of the previous code executionnextStep- The next step to execute or NULL for nonecontinuation- The continuation of the execution
-
execute
protected java.lang.Void execute(java.lang.Void input, Continuation<?> continuation)This method must be implemented by subclasses to provide the actual functionality of this step.- Specified by:
executein classCoroutineStep<java.lang.Void,java.lang.Void>- Parameters:
input- The input valuecontinuation- The continuation of the execution- Returns:
- The result of the execution
-
getServerSocketChannel
protected java.nio.channels.AsynchronousServerSocketChannel getServerSocketChannel(Continuation<?> continuation) throws java.io.IOException
Returns the channel to be used by this step. This first checks the currently exexcuting coroutine in the continuation parameter for an existingSERVER_SOCKET_CHANNELrelation. If that doesn't exists or if it contains a closed channel a newAsynchronousServerSocketChannelwill be opened and stored in the state object.- Parameters:
continuation- The continuation to query for an existing channel- Returns:
- The channel
- Throws:
java.io.IOException- If opening the channel fails
-
getSocketAddress
protected java.net.SocketAddress getSocketAddress(Continuation<?> continuation)
Returns the address of the socket to connect to.- Parameters:
continuation- The current continuation- Returns:
- The socket address
-
getSocketAddressFactory
protected java.util.function.Function<Continuation<?>,java.net.SocketAddress> getSocketAddressFactory()
Returns the socket address factory of this step.- Returns:
- The socket address factory function
-
-