Package de.esoco.coroutine
Class Continuation<T>
- java.lang.Object
-
- org.obrel.core.RelatedObject
-
- de.esoco.coroutine.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.ExecutorA continuation represents the state of a coroutine execution. It can be used to carry state between coroutine execution steps by setting relations on it. EachCoroutineStepreceives the continuation of it's execution as an argument to it's execution methods.
-
-
Constructor Summary
Constructors Constructor Description Continuation(CoroutineScope scope, Coroutine<?,T> coroutine)Creates a new instance for the execution of the givenCoroutinein a certain scope.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description voidawait()Awaits the completion of the coroutine execution.booleanawait(long timeout, java.util.concurrent.TimeUnit unit)Awaits the completion of this continuation but only until a timeout is reached.voidcancel()Cancels the execution of the associatedCoroutineat the next suspension point.CoroutineContextcontext()Returns the context of the executed coroutine.<V> voidcontinueAccept(java.util.concurrent.CompletableFuture<V> rPreviousExecution, java.util.function.Consumer<V> fNext)Continues the execution of aCompletableFutureby consuming it's result.<I,O>
voidcontinueApply(java.util.concurrent.CompletableFuture<I> previousExecution, java.util.function.Function<I,O> next, CoroutineStep<O,?> nextStep)Continues the execution of aCompletableFutureby applying a function to it's result and then either invoking the next step in a chain or finish the execution.voiderrorHandled()Marks an error of this continuation as handled.voidexecute(java.lang.Runnable command)Forwards the execution to the executor of theCoroutineContext.<O> Ofail(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> VgetConfiguration(org.obrel.core.RelationType<V> configType)Returns a configuration value with a default value of NULL.<V> VgetConfiguration(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.ThrowablegetError()Returns the error exception that caused a coroutine cancelation.TgetResult()Return the result of the coroutine execution.TgetResult(long timeout, java.util.concurrent.TimeUnit unit)Return the result of the coroutine execution or throws aCoroutineExceptionif a timeout is reached.<V> VgetState(org.obrel.core.RelationType<V> stateType)Returns a state value with a default value of NULL.<V> VgetState(org.obrel.core.RelationType<V> stateType, V defaultValue)Returns the value of a runtime state relation of the current execution.longid()Returns the unique ID of this instance.booleanisCancelled()Checks if the execution of the coroutine has been cancelled.booleanisFinished()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 andfinish(Object)has been invoked.CoroutineScopescope()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.StringtoString()-
Methods inherited from class org.obrel.core.RelatedObject
deleteRelation, get, getRelation, getRelations, notifyRelationListeners, readRelations, relationsEqual, relationsHashCode, relationsString, set, set, transform, writeRelations
-
-
-
-
Constructor Detail
-
Continuation
public Continuation(CoroutineScope scope, Coroutine<?,T> coroutine)
Creates a new instance for the execution of the givenCoroutinein a certain scope.- Parameters:
scope- The coroutine contextcoroutine- The coroutine that is executed with this continuation
-
-
Method Detail
-
await
public void await()
Awaits the completion of the coroutine execution. Other thangetResult()this will not throw an exception on failure or cancellation. An application must check these by itself if needed throughgetError()andisCancelled().
-
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 thangetResult(long, TimeUnit)this will not throw an exception on failure or cancellation. An application must check these by itself if needed throughgetError()andisCancelled().- Parameters:
timeout- The timeout valueunit- 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 associatedCoroutineat 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 aCompletableFutureby 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 continuefNext- 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 aCompletableFutureby 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 continuenext- The next code to executenextStep- 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 theCoroutineContext.- Specified by:
executein interfacejava.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 throughgetError(). It will also invokeCoroutineScope.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)
-
getChannel
public final <C> Channel<C> getChannel(ChannelId<C> id)
Duplicated here for easier access during coroutine execution.- See Also:
CoroutineScope.getChannel(ChannelId)
-
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 typedefaultValue- 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 aCancellationExceptionwill be thrown. If it has failed with an error aCoroutineExceptionwill 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 aCoroutineExceptionif a timeout is reached. If this continuation has been cancelled aCancellationExceptionwill be thrown. If it has failed with an error aCoroutineExceptionwill be thrown.- Parameters:
timeout- The timeout valueunit- 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 occurredjava.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 typedefaultValue- 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 methodgetError()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 withisCancelled(). If it has been cancelled because of and error the methodgetError()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 andfinish(Object)has been invoked. If the execution of the coroutine is cancelled (by invokingcancel()) 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 ofSuspensionthat 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 withSuspension.resume(Object)or by setting it into the suspension withSuspension.withValue(Object).- Parameters:
suspendingStep- The step initiating the suspensionsuspendedStep- 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 callsuspend(CoroutineStep, CoroutineStep)instead.- Parameters:
suspension- The suspension to suspend to- Returns:
- The suspension object
-
toString
public java.lang.String toString()
- Overrides:
toStringin classorg.obrel.core.RelatedObject
-
-