Class Continuation<T>

  • All Implemented Interfaces:
    java.util.concurrent.Executor, org.obrel.core.Relatable

    public class Continuation<T>
    extends org.obrel.core.RelatedObject
    implements java.util.concurrent.Executor
    A continuation represents the state of a coroutine execution. It can be used to carry state between coroutine execution steps by setting relations on it. Each CoroutineStep receives the continuation of it's execution as an argument to it's execution methods.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void await()
      Awaits the completion of the coroutine execution.
      boolean await​(long timeout, java.util.concurrent.TimeUnit unit)
      Awaits the completion of this continuation but only until a timeout is reached.
      void cancel()
      Cancels the execution of the associated Coroutine at the next suspension point.
      CoroutineContext context()
      Returns the context of the executed coroutine.
      <V> void continueAccept​(java.util.concurrent.CompletableFuture<V> rPreviousExecution, java.util.function.Consumer<V> fNext)
      Continues the execution of a CompletableFuture by consuming it's result.
      <I,​O>
      void
      continueApply​(java.util.concurrent.CompletableFuture<I> previousExecution, java.util.function.Function<I,​O> next, CoroutineStep<O,​?> nextStep)
      Continues the execution of a CompletableFuture by applying a function to it's result and then either invoking the next step in a chain or finish the execution.
      void errorHandled()
      Marks an error of this continuation as handled.
      void execute​(java.lang.Runnable command)
      Forwards the execution to the executor of the CoroutineContext.
      <O> O fail​(java.lang.Throwable error)
      Signals that an error occurred during the coroutine execution.
      <C> Channel<C> getChannel​(ChannelId<C> id)
      Duplicated here for easier access during coroutine execution.
      <V> V getConfiguration​(org.obrel.core.RelationType<V> configType)
      Returns a configuration value with a default value of NULL.
      <V> V getConfiguration​(org.obrel.core.RelationType<V> configType, V defaultValue)
      Returns the value of a configuration relation.
      Coroutine<?,​?> getCurrentCoroutine()
      Returns either the root coroutine or, if subroutines have been started from it, the currently executing subroutine.
      Suspension<?> getCurrentSuspension()
      Returns the current suspension.
      java.lang.Throwable getError()
      Returns the error exception that caused a coroutine cancelation.
      T getResult()
      Return the result of the coroutine execution.
      T getResult​(long timeout, java.util.concurrent.TimeUnit unit)
      Return the result of the coroutine execution or throws a CoroutineException if a timeout is reached.
      <V> V getState​(org.obrel.core.RelationType<V> stateType)
      Returns a state value with a default value of NULL.
      <V> V getState​(org.obrel.core.RelationType<V> stateType, V defaultValue)
      Returns the value of a runtime state relation of the current execution.
      long id()
      Returns the unique ID of this instance.
      boolean isCancelled()
      Checks if the execution of the coroutine has been cancelled.
      boolean isFinished()
      Checks if the execution of the coroutine has finished.
      Continuation<T> onCancel​(java.util.function.Consumer<Continuation<T>> runOnCancel)
      Sets a function to be run if the execution of this instance is cancelled.
      Continuation<T> onError​(java.util.function.Consumer<Continuation<T>> runOnError)
      Sets a function to be run if the execution of this instance fails.
      Continuation<T> onFinish​(java.util.function.Consumer<Continuation<T>> runWhenDone)
      Sets a function that will be invoked after the coroutine has successfully finished execution and finish(Object) has been invoked.
      CoroutineScope scope()
      Returns the scope in which the coroutine is executed.
      <V> Suspension<V> suspend​(CoroutineStep<?,​V> suspendingStep, CoroutineStep<V,​?> suspendedStep)
      Suspends an invoking step for later invocation.
      <V> Suspension<V> suspendTo​(Suspension<V> suspension)
      Suspends an invoking step for later invocation with the given instance of a suspension subclass.
      java.lang.String toString()
      • 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 org.obrel.core.Relatable

        deleteRelation, deleteRelations, getAll, getOption, getRelationCount, getRelations, hasFlag, hasRelation, hasRelations, init, set, set, set, setOption, streamRelations
    • Constructor Detail

      • Continuation

        public Continuation​(CoroutineScope scope,
                            Coroutine<?,​T> coroutine)
        Creates a new instance for the execution of the given Coroutine in a certain scope.
        Parameters:
        scope - The coroutine context
        coroutine - The coroutine that is executed with this continuation
    • Method Detail

      • await

        public void await()
        Awaits the completion of the coroutine execution. Other than getResult() this will not throw an exception on failure or cancellation. An application must check these by itself if needed through getError() and isCancelled().
      • await

        public boolean await​(long timeout,
                             java.util.concurrent.TimeUnit unit)
        Awaits the completion of this continuation but only until a timeout is reached. If the timeout is reached before completion the returned value will be FALSE. Other than getResult(long, TimeUnit) this will not throw an exception on failure or cancellation. An application must check these by itself if needed through getError() and isCancelled().
        Parameters:
        timeout - The timeout value
        unit - The time unit of the the timeout
        Returns:
        TRUE if the coroutine has finished, FALSE if the timeout elapsed
      • cancel

        public void cancel()
        Cancels the execution of the associated Coroutine at the next suspension point. Due to the nature of the cooperative concurrency of coroutines there is no guarantee as to when the cancellation will occur. The bMayInterruptIfRunning parameter is ignored because the thread on which the current step is running is not known.
      • context

        public final CoroutineContext context()
        Returns the context of the executed coroutine.
        Returns:
        The coroutine context
      • continueAccept

        public final <V> void continueAccept​(java.util.concurrent.CompletableFuture<V> rPreviousExecution,
                                             java.util.function.Consumer<V> fNext)
        Continues the execution of a CompletableFuture by consuming it's result. This is typically done by suspending steps that resume the coroutine execution later. Coroutine steps must always invoke a continue method to progress to a subsequent step and not use the methods of the future directly.
        Parameters:
        rPreviousExecution - The future to continue
        fNext - The next code to execute
      • continueApply

        public final <I,​O> void continueApply​(java.util.concurrent.CompletableFuture<I> previousExecution,
                                                    java.util.function.Function<I,​O> next,
                                                    CoroutineStep<O,​?> nextStep)
        Continues the execution of a CompletableFuture by applying a function to it's result and then either invoking the next step in a chain or finish the execution. Coroutine steps must always invoke a continue method to progress to a subsequent step and not use the methods of the future directly.
        Parameters:
        previousExecution - The future to continue
        next - The next code to execute
        nextStep - The next step
      • errorHandled

        public void errorHandled()
        Marks an error of this continuation as handled. This will remove this instance from the failed continuations of the scope and thus prevent the scope from throwing an exception because of this error upon completion.
        Throws:
        java.lang.IllegalStateException - If this instance has no error
      • execute

        public void execute​(java.lang.Runnable command)
        Forwards the execution to the executor of the CoroutineContext.
        Specified by:
        execute in interface java.util.concurrent.Executor
        See Also:
        Executor.execute(Runnable)
      • fail

        public <O> O fail​(java.lang.Throwable error)
        Signals that an error occurred during the coroutine execution. This will set this continuation to canceled and makes the error exception available through getError(). It will also invoke CoroutineScope.fail(Continuation) on the scope this continuation runs in.
        Parameters:
        error - The exception that caused the error
        Returns:
        Always NULL but declared with a generic type so that it can be used directly as a functional argument to CompletableFuture.exceptionally(Function)
      • getConfiguration

        public <V> V getConfiguration​(org.obrel.core.RelationType<V> configType)
        Returns a configuration value with a default value of NULL.
        See Also:
        getConfiguration(RelationType, Object)
      • getConfiguration

        public <V> V getConfiguration​(org.obrel.core.RelationType<V> configType,
                                      V defaultValue)
        Returns the value of a configuration relation. The lookup has the precedence continuation (this) -> scope -> context -> coroutine, meaning that a configuration in an earlier stage overrides the later ones. This means that a (static) configuration in a coroutine definition can be overridden by the runtime stages.

        Coroutine steps that want to modify the configuration of the root coroutine they are running in should set the configuration value on the the continuation. To limit the change to the currently running coroutine (e.g. a subroutine) configurations should be set on getCurrentCoroutine() instead.

        Parameters:
        configType - The configuraton relation type
        defaultValue - The default value if no state relation exists
        Returns:
        The configuration value (may be NULL)
      • getCurrentCoroutine

        public final Coroutine<?,​?> getCurrentCoroutine()
        Returns either the root coroutine or, if subroutines have been started from it, the currently executing subroutine.
        Returns:
        The currently executing coroutine
      • getCurrentSuspension

        public final Suspension<?> getCurrentSuspension()
        Returns the current suspension.
        Returns:
        The current suspension or NULL for none
      • getError

        public java.lang.Throwable getError()
        Returns the error exception that caused a coroutine cancelation.
        Returns:
        The error or NULL for none
      • getResult

        public T getResult()
        Return the result of the coroutine execution. If this continuation has been cancelled a CancellationException will be thrown. If it has failed with an error a CoroutineException will be thrown.
        Returns:
        The result
      • getResult

        public T getResult​(long timeout,
                           java.util.concurrent.TimeUnit unit)
        Return the result of the coroutine execution or throws a CoroutineException if a timeout is reached. If this continuation has been cancelled a CancellationException will be thrown. If it has failed with an error a CoroutineException will be thrown.
        Parameters:
        timeout - The timeout value
        unit - The time unit of the the timeout
        Returns:
        The result The result of the execution
        Throws:
        CoroutineException - If the timeout has elapsed before finishing or an error occurred
        java.util.concurrent.CancellationException - If the coroutine had been cancelled
      • getState

        public <V> V getState​(org.obrel.core.RelationType<V> stateType)
        Returns a state value with a default value of NULL.
        See Also:
        getState(RelationType, Object)
      • getState

        public <V> V getState​(org.obrel.core.RelationType<V> stateType,
                              V defaultValue)
        Returns the value of a runtime state relation of the current execution. This will first look for the value in currently executing coroutine (either the root or a subroutine). If not found there the value will be queried from this continuation first and if not there too, from the scope. To the a runtime state value the respective relation needs to be set on the appropriate stage (coroutine, continuation, scope).
        Parameters:
        stateType - The state relation type
        defaultValue - The default value if no state relation exists
        Returns:
        The runtime state value (may be null)
      • id

        public final long id()
        Returns the unique ID of this instance.
        Returns:
        The continuation ID
      • isCancelled

        public boolean isCancelled()
        Checks if the execution of the coroutine has been cancelled. If it has been cancelled because of and error the method getError() will return an exception.
        Returns:
        TRUE if the execution has been cancelled
      • isFinished

        public boolean isFinished()
        Checks if the execution of the coroutine has finished. Whether it has finished successfully or by cancelation can be checked with isCancelled(). If it has been cancelled because of and error the method getError() will return an exception.
        Returns:
        TRUE if the execution has finished
      • onCancel

        public Continuation<T> onCancel​(java.util.function.Consumer<Continuation<T>> runOnCancel)
        Sets a function to be run if the execution of this instance is cancelled.
        Parameters:
        runOnCancel - A function to be run on cancellation
        Returns:
        This instance to allow additional invocations
      • onError

        public Continuation<T> onError​(java.util.function.Consumer<Continuation<T>> runOnError)
        Sets a function to be run if the execution of this instance fails.
        Parameters:
        runOnError - A function to be run on cancellation
        Returns:
        This instance to allow additional invocations
      • onFinish

        public Continuation<T> onFinish​(java.util.function.Consumer<Continuation<T>> runWhenDone)
        Sets a function that will be invoked after the coroutine has successfully finished execution and finish(Object) has been invoked. If the execution of the coroutine is cancelled (by invoking cancel()) the code will not be invoked. The code will be run directly, not asynchronously.
        Parameters:
        runWhenDone - The consumer to process this continuation with when the execution has finished
        Returns:
        This instance to allow additional invocations
      • scope

        public final CoroutineScope scope()
        Returns the scope in which the coroutine is executed.
        Returns:
        The coroutine scope
      • suspend

        public <V> Suspension<V> suspend​(CoroutineStep<?,​V> suspendingStep,
                                         CoroutineStep<V,​?> suspendedStep)
        Suspends an invoking step for later invocation. Returns an instance of Suspension that contains the state necessary for resuming the execution. The suspension will not contain an input value because it is typically not know upon suspension. It must be provided later, either when resuming with Suspension.resume(Object) or by setting it into the suspension with Suspension.withValue(Object).
        Parameters:
        suspendingStep - The step initiating the suspension
        suspendedStep - The step to suspend
        Returns:
        A new suspension object
      • suspendTo

        public <V> Suspension<V> suspendTo​(Suspension<V> suspension)
        Suspends an invoking step for later invocation with the given instance of a suspension subclass. This method is only intended for special suspension cases. Most step implementations should call suspend(CoroutineStep, CoroutineStep) instead.
        Parameters:
        suspension - The suspension to suspend to
        Returns:
        The suspension object
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class org.obrel.core.RelatedObject