Class AsynchronousSocketStep

  • All Implemented Interfaces:
    de.esoco.lib.property.Fluent<CoroutineStep<java.nio.ByteBuffer,​java.nio.ByteBuffer>>, org.obrel.core.FluentRelatable<CoroutineStep<java.nio.ByteBuffer,​java.nio.ByteBuffer>>, org.obrel.core.Relatable
    Direct Known Subclasses:
    SocketReceive, SocketSend

    public abstract class AsynchronousSocketStep
    extends AsynchronousChannelStep<java.nio.ByteBuffer,​java.nio.ByteBuffer>
    The base class for coroutine steps that perform communication on instances of AsynchronousSocketChannel. The channel will be opened and connected as necessary. It may also be provided before the step is invoked in a state relation with the type SOCKET_CHANNEL. If the channel is opened by this step it will have the MetaTypes.MANAGED flag so that it will be automatically closed when the CoroutineScope finishes.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static org.obrel.core.RelationType<java.nio.channels.AsynchronousSocketChannel> SOCKET_CHANNEL
      State: the AsynchronousSocketChannel that the steps in a coroutine operate on.
    • Constructor Summary

      Constructors 
      Constructor Description
      AsynchronousSocketStep​(java.util.function.Function<Continuation<?>,​java.net.SocketAddress> getSocketAddress)
      Creates a new instance that connects to the socket with the address provided by the given factory.
    • Method Summary

      All Methods Instance Methods Abstract Methods Concrete Methods 
      Modifier and Type Method Description
      protected java.nio.ByteBuffer execute​(java.nio.ByteBuffer input, Continuation<?> continuation)
      This method must be implemented by subclasses to provide the actual functionality of this step.
      protected java.net.SocketAddress getSocketAddress​(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.
      protected java.nio.channels.AsynchronousSocketChannel getSocketChannel​(Continuation<?> continuation)
      Returns the channel to be used by this step.
      protected abstract boolean performAsyncOperation​(int bytesProcessed, java.nio.channels.AsynchronousSocketChannel channel, java.nio.ByteBuffer data, AsynchronousChannelStep.ChannelCallback<java.lang.Integer,​java.nio.channels.AsynchronousSocketChannel> callback)
      Implementation of the ChannelOperation functional interface method signature.
      protected abstract void performBlockingOperation​(java.nio.channels.AsynchronousSocketChannel channel, java.nio.ByteBuffer data)
      Must be implemented for the blocking execution of a step.
      void runAsync​(java.util.concurrent.CompletableFuture<java.nio.ByteBuffer> previousExecution, CoroutineStep<java.nio.ByteBuffer,​?> nextStep, Continuation<?> continuation)
      Runs this execution step asynchronously as a continuation of a previous code execution in a CompletableFuture and proceeds to the next step afterwards.
      • Methods inherited from class org.obrel.core.RelatedObject

        deleteRelation, get, getRelation, getRelations, notifyRelationListeners, readRelations, relationsEqual, relationsHashCode, relationsString, set, set, transform, writeRelations
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
      • Methods inherited from interface de.esoco.lib.property.Fluent

        _with
      • Methods inherited from interface org.obrel.core.FluentRelatable

        with, with, with
      • Methods inherited from interface org.obrel.core.Relatable

        deleteRelation, deleteRelation, deleteRelations, get, getAll, getOption, getRelation, getRelationCount, getRelations, getRelations, hasFlag, hasRelation, hasRelations, init, set, set, set, set, set, setOption, streamRelations, transform
    • Field Detail

      • SOCKET_CHANNEL

        public static final org.obrel.core.RelationType<java.nio.channels.AsynchronousSocketChannel> SOCKET_CHANNEL
        State: the AsynchronousSocketChannel that the steps in a coroutine operate on.
    • Constructor Detail

      • AsynchronousSocketStep

        public AsynchronousSocketStep​(java.util.function.Function<Continuation<?>,​java.net.SocketAddress> getSocketAddress)
        Creates a new instance that connects to the 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 type SOCKET_CHANNEL.
        Parameters:
        getSocketAddress - A function that provides the socket address to connect to from the current continuation
    • Method Detail

      • runAsync

        public void runAsync​(java.util.concurrent.CompletableFuture<java.nio.ByteBuffer> previousExecution,
                             CoroutineStep<java.nio.ByteBuffer,​?> nextStep,
                             Continuation<?> continuation)
        Runs this execution step asynchronously as a continuation of a previous code execution in a CompletableFuture and 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 Suspension by invoking Continuation.suspend(CoroutineStep, CoroutineStep) on the next step. If the condition that caused the suspension resolves the coroutine execution can be resumed by calling Suspension.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:
        runAsync in class CoroutineStep<java.nio.ByteBuffer,​java.nio.ByteBuffer>
        Parameters:
        previousExecution - The future of the previous code execution
        nextStep - The next step to execute or NULL for none
        continuation - The continuation of the execution
      • execute

        protected java.nio.ByteBuffer execute​(java.nio.ByteBuffer input,
                                              Continuation<?> continuation)
        This method must be implemented by subclasses to provide the actual functionality of this step.
        Specified by:
        execute in class CoroutineStep<java.nio.ByteBuffer,​java.nio.ByteBuffer>
        Parameters:
        input - The input value
        continuation - The continuation of the execution
        Returns:
        The result of the execution
      • 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
      • getSocketChannel

        protected java.nio.channels.AsynchronousSocketChannel getSocketChannel​(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 existing SOCKET_CHANNEL relation. If that doesn't exists or the channel is closed a new AsynchronousSocketChannel will be opened and stored in the coroutine relation. Using the coroutine to store the channel allows coroutines to be structured so that multiple subroutines perform communication on different channels.
        Parameters:
        continuation - The continuation to query for an existing channel
        Returns:
        The socket channel
        Throws:
        java.io.IOException - If opening the channel fails
      • performBlockingOperation

        protected abstract void performBlockingOperation​(java.nio.channels.AsynchronousSocketChannel channel,
                                                         java.nio.ByteBuffer data)
                                                  throws java.lang.Exception
        Must be implemented for the blocking execution of a step. It receives an AsynchronousSocketChannel which must be accessed through the blocking API (like Future.get()).
        Parameters:
        channel - The channel to perform the operation on
        data - The byte buffer for the operation data
        Throws:
        java.lang.Exception - Any kind of exception may be thrown