Class Select<I,​O>

  • All Implemented Interfaces:
    de.esoco.lib.property.Fluent<CoroutineStep<I,​O>>, org.obrel.core.FluentRelatable<CoroutineStep<I,​O>>, org.obrel.core.Relatable

    public class Select<I,​O>
    extends CoroutineStep<I,​O>
    A coroutine step that suspends the coroutine execution until the first matching result of several other asynchronously executed coroutines are available. The selecting coroutine is then resumed with the selected result. By default the result of the coroutine that finished first will be selected but that can be modified by setting a different condition with when(Predicate). If a result is selected all coroutines that are sill running will be cancelled and execution of the selecting coroutine is resumed.

    The main purpose of this step is to non-blockingly select the first result from other suspending coroutines although it can be used with arbitrary coroutines and steps. It should be noted that if both suspending and non-suspending selection targets are used the non-suspending targets will almost always be selected. Even when using only suspending coroutines the selection will be slightly biased towards the first coroutine because the coroutines need to be launched sequentially, giving the first coroutine(s) a head start.

    To select more than one result from the child coroutines the related step implementation Collect can be used.

    • Constructor Summary

      Constructors 
      Constructor Description
      Select​(java.util.Collection<Coroutine<? super I,​? extends O>> rFromCoroutines)
      Creates a new instance.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      protected O execute​(I input, Continuation<?> continuation)
      This method must be implemented by subclasses to provide the actual functionality of this step.
      Select<I,​O> or​(Coroutine<? super I,​? extends O> rCoroutine)
      Creates a new instance that selects from an additional coroutine.
      Select<I,​O> or​(CoroutineStep<? super I,​? extends O> rStep)
      Creates a new instance that selects from an additional step.
      void runAsync​(java.util.concurrent.CompletableFuture<I> previousExecution, CoroutineStep<O,​?> 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.
      static <I,​O>
      Select<I,​O>
      select​(Coroutine<? super I,​? extends O>... rFromCoroutines)
      Suspends the coroutine execution until one coroutine finishes and then resumes the execution with the result.
      static <I,​O>
      Select<I,​O>
      select​(CoroutineStep<? super I,​? extends O>... rFromSteps)
      Suspends the coroutine execution until one coroutine step finishes.
      Select<I,​O> when​(java.util.function.Predicate<Continuation<?>> pSelectCriteria)
      Adds a condition for the result selection.
      • 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
    • Constructor Detail

      • Select

        public Select​(java.util.Collection<Coroutine<? super I,​? extends O>> rFromCoroutines)
        Creates a new instance.
        Parameters:
        rFromCoroutines - The coroutines to select from
    • Method Detail

      • select

        @SafeVarargs
        public static <I,​O> Select<I,​O> select​(Coroutine<? super I,​? extends O>... rFromCoroutines)
        Suspends the coroutine execution until one coroutine finishes and then resumes the execution with the result. By default the result of the first finished coroutine is selected. That can be modified by providing a different selection condition to when(Predicate) which will return a new Select instance. Modified instances that select from additional coroutines or steps can be created with or(Coroutine) and or(CoroutineStep).
        Parameters:
        rFromCoroutines - The coroutines to select from
        Returns:
        A new step instance
      • select

        @SafeVarargs
        public static <I,​O> Select<I,​O> select​(CoroutineStep<? super I,​? extends O>... rFromSteps)
        Suspends the coroutine execution until one coroutine step finishes. The step arguments will be wrapped into new coroutines and then handed to select(Coroutine...).
        Parameters:
        rFromSteps - The coroutine steps to select from
        Returns:
        A new step instance
      • or

        public Select<I,​O> or​(Coroutine<? super I,​? extends O> rCoroutine)
        Creates a new instance that selects from an additional coroutine.
        Parameters:
        rCoroutine - The additional coroutine to select from
        Returns:
        The new instance
      • or

        public Select<I,​O> or​(CoroutineStep<? super I,​? extends O> rStep)
        Creates a new instance that selects from an additional step. The step will be wrapped into a new coroutine and handed to or(Coroutine).
        Parameters:
        rStep - The additional step to select from
        Returns:
        The new instance
      • runAsync

        public void runAsync​(java.util.concurrent.CompletableFuture<I> previousExecution,
                             CoroutineStep<O,​?> 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<I,​O>
        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
      • when

        public Select<I,​O> when​(java.util.function.Predicate<Continuation<?>> pSelectCriteria)
        Adds a condition for the result selection. If a succefully finished continuation matches the given predicate it will be selected as the step result.
        Parameters:
        pSelectCriteria - A condition that checks if a result should be selected
        Returns:
        A new step instance
      • execute

        protected O execute​(I input,
                            Continuation<?> continuation)
        This method must be implemented by subclasses to provide the actual functionality of this step.
        Specified by:
        execute in class CoroutineStep<I,​O>
        Parameters:
        input - The input value
        continuation - The continuation of the execution
        Returns:
        The result of the execution