Interface Context
- All Known Subinterfaces:
ObjectContext
,SharedObjectContext
,SharedWorkflowContext
,WorkflowContext
Error handling
All methods of this interface, and related interfaces, throws eitherTerminalException
or
AbortedExecutionException
, where the former can be caught and acted upon, while the
latter MUST NOT be caught, but simply propagated for clean up purposes.
Serialization and Deserialization
The methods of this interface that need to serialize or deserialize payloads have an overload both acceptingClass
or TypeTag
. Depending on your case, you might use the Class
overload for simple types, and TypeRef
for generic types:
String result = ctx.run(
"my-http-request",
String.class,
() -> doHttpRequest().getResult()
).await();
List<String> result = ctx.run(
"my-http-request",
new TypeRef<>(){ },
() -> doHttpRequest().getResult()
).await();
By default, Jackson Databind will be used for all serialization/deserialization. Check SerdeFactory
for more details on how to customize that.
Thread safety
This interface MUST NOT be accessed concurrently since it can lead to different orderings of user actions, corrupting the execution of the invocation.-
Method Summary
Modifier and TypeMethodDescription<T> Awakeable
<T> Create anAwakeable
, addressable throughAwakeable.id()
.default <T> Awakeable
<T> Create anAwakeable
, addressable throughAwakeable.id()
.Create a newAwakeableHandle
for the provided identifier.<T,
R> CallDurableFuture <R> Invoke another Restate service method.default InvocationHandle
<Slice> invocationHandle
(String invocationId) LikeinvocationHandle(String, Class)
, without providing a response parser<R> InvocationHandle
<R> invocationHandle
(String invocationId, TypeTag<R> responseTypeTag) default <R> InvocationHandle
<R> invocationHandle
(String invocationId, Class<R> responseClazz) Get anInvocationHandle
for an already existing invocation.random()
Returns a deterministic random.request()
default void
run
(ThrowingRunnable runnable) Likerun(Class, ThrowingSupplier)
without output.default <T> T
run
(TypeTag<T> typeTag, ThrowingSupplier<T> action) Likerun(String, TypeTag, ThrowingSupplier)
, without a namedefault <T> T
run
(Class<T> clazz, ThrowingSupplier<T> action) Likerun(String, Class, ThrowingSupplier)
, without a namedefault void
run
(String name, ThrowingRunnable runnable) Likerun(String, Class, ThrowingSupplier)
without output.default void
run
(String name, RetryPolicy retryPolicy, ThrowingRunnable runnable) Likerun(String, ThrowingRunnable)
, but without a return value and using a custom retry policy.default <T> T
run
(String name, TypeTag<T> typeTag, ThrowingSupplier<T> action) Likerun(String, Class, ThrowingSupplier)
, but providing aTypeTag
.default <T> T
run
(String name, TypeTag<T> typeTag, RetryPolicy retryPolicy, ThrowingSupplier<T> action) Likerun(String, TypeTag, ThrowingSupplier)
, but using a custom retry policy.default <T> T
run
(String name, Class<T> clazz, ThrowingSupplier<T> action) Execute a closure, recording the result value in the journal.default <T> T
run
(String name, Class<T> clazz, RetryPolicy retryPolicy, ThrowingSupplier<T> action) Likerun(String, Class, ThrowingSupplier)
, but using a custom retry policy.default DurableFuture
<Void> runAsync
(ThrowingRunnable runnable) LikerunAsync(String, Class, ThrowingSupplier)
without output.default <T> DurableFuture
<T> runAsync
(TypeTag<T> typeTag, ThrowingSupplier<T> action) LikerunAsync(String, TypeTag, ThrowingSupplier)
, without a namedefault <T> DurableFuture
<T> runAsync
(Class<T> clazz, ThrowingSupplier<T> action) LikerunAsync(String, Class, ThrowingSupplier)
, without a namedefault DurableFuture
<Void> runAsync
(String name, ThrowingRunnable runnable) LikerunAsync(String, Class, ThrowingSupplier)
without output.default DurableFuture
<Void> runAsync
(String name, RetryPolicy retryPolicy, ThrowingRunnable runnable) LikerunAsync(String, Class, ThrowingSupplier)
, but without an output and using a custom retry policy.default <T> DurableFuture
<T> runAsync
(String name, TypeTag<T> typeTag, ThrowingSupplier<T> action) LikerunAsync(String, Class, ThrowingSupplier)
, but providing aTypeTag
.<T> DurableFuture
<T> runAsync
(String name, TypeTag<T> typeTag, RetryPolicy retryPolicy, ThrowingSupplier<T> action) LikerunAsync(String, TypeTag, ThrowingSupplier)
, but using a custom retry policy.default <T> DurableFuture
<T> runAsync
(String name, Class<T> clazz, ThrowingSupplier<T> action) Execute a closure asynchronously.default <T> DurableFuture
<T> runAsync
(String name, Class<T> clazz, RetryPolicy retryPolicy, ThrowingSupplier<T> action) LikerunAsync(String, Class, ThrowingSupplier)
, but using a custom retry policy.default <T,
R> InvocationHandle <R> Invoke another Restate service without waiting for the response.<T,
R> InvocationHandle <R> Invoke another Restate service without waiting for the response.default void
Causes the current execution of the function invocation to sleep for the given duration.Causes the start of a timer for the given duration.default DurableFuture
<Void> Causes the start of a timer for the given duration.
-
Method Details
-
request
HandlerRequest request() -
call
Invoke another Restate service method.- Parameters:
request
- Request object. For each service, a class called<your_class_name>Handlers
is generated containing the request builders.- Returns:
- an
DurableFuture
that wraps the Restate service method result.
-
send
Invoke another Restate service without waiting for the response.- Parameters:
request
- Request object. For each service, a class called<your_class_name>Handlers
is generated containing the request builders.- Returns:
- an
InvocationHandle
that can be used to retrieve the invocation id, cancel the invocation, attach to its result.
-
send
Invoke another Restate service without waiting for the response.- Parameters:
request
- Request object. For each service, a class called<your_class_name>Handlers
is generated containing the request builders.delay
- the delay to send the request- Returns:
- an
InvocationHandle
that can be used to retrieve the invocation id, cancel the invocation, attach to its result.
-
invocationHandle
-
invocationHandle
Get anInvocationHandle
for an already existing invocation. This will let you interact with a running invocation, for example to cancel it or retrieve its result.- Parameters:
invocationId
- The invocation to interact with.responseClazz
- The response class.
-
invocationHandle
LikeinvocationHandle(String, Class)
, without providing a response parser -
sleep
Causes the current execution of the function invocation to sleep for the given duration.- Parameters:
duration
- for which to sleep.
-
timer
Causes the start of a timer for the given duration. You can await on the timer end by invokingDurableFuture.await()
.- Parameters:
duration
- for which to sleep.
-
timer
Causes the start of a timer for the given duration. You can await on the timer end by invokingDurableFuture.await()
.- Parameters:
name
- name used for observabilityduration
- for which to sleep.
-
run
Execute a closure, recording the result value in the journal. The result value will be re-played in case of re-invocation (e.g. because of failure recovery or suspension point) without re-executing the closure.
If the result type contains generic types, e.g. aString result = ctx.run( "my-http-request", String.class, () -> doHttpRequest().getResult() ).await();
List<String>
, you should userun(String, TypeTag, ThrowingSupplier)
. SeeContext
for more details about serialization and deserialization.You can name this closure using the
name
parameter. This name will be available in the observability tools.The closure should tolerate retries, that is Restate might re-execute the closure multiple times until it records a result. You can control and limit the amount of retries using
run(String, Class, RetryPolicy, ThrowingSupplier)
.Error handling: Errors occurring within this closure won't be propagated to the caller, unless they are
TerminalException
. Consider the following code:
To propagate run failures to the call-site, make sure to wrap them in// Bad usage of try-catch outside the run try { ctx.run(() -> { throw new IllegalStateException(); }).await(); } catch (IllegalStateException e) { // This will never be executed, // but the error will be retried by Restate, // following the invocation retry policy. } // Good usage of try-catch outside the run try { ctx.run(() -> { throw new TerminalException("my error"); }).await(); } catch (TerminalException e) { // This is invoked }
TerminalException
.- Type Parameters:
T
- type of the return value.- Parameters:
name
- name of the side effect.clazz
- the class of the return value, used to serialize/deserialize it.action
- closure to execute.- Returns:
- value of the run operation.
- Throws:
TerminalException
-
run
default <T> T run(String name, TypeTag<T> typeTag, RetryPolicy retryPolicy, ThrowingSupplier<T> action) throws TerminalException Likerun(String, TypeTag, ThrowingSupplier)
, but using a custom retry policy.When a retry policy is not specified, the
run
will be retried using the Restate invoker retry policy, which by default retries indefinitely.- Throws:
TerminalException
- See Also:
-
run
default <T> T run(String name, Class<T> clazz, RetryPolicy retryPolicy, ThrowingSupplier<T> action) throws TerminalException Likerun(String, Class, ThrowingSupplier)
, but using a custom retry policy.When a retry policy is not specified, the
run
will be retried using the Restate invoker retry policy, which by default retries indefinitely.- Throws:
TerminalException
- See Also:
-
run
default <T> T run(String name, TypeTag<T> typeTag, ThrowingSupplier<T> action) throws TerminalException Likerun(String, Class, ThrowingSupplier)
, but providing aTypeTag
.See
Context
for more details about serialization and deserialization.- Throws:
TerminalException
- See Also:
-
run
Likerun(String, TypeTag, ThrowingSupplier)
, without a name- Throws:
TerminalException
- See Also:
-
run
Likerun(String, Class, ThrowingSupplier)
, without a name- Throws:
TerminalException
- See Also:
-
run
default void run(String name, RetryPolicy retryPolicy, ThrowingRunnable runnable) throws TerminalException Likerun(String, ThrowingRunnable)
, but without a return value and using a custom retry policy.When a retry policy is not specified, the
run
will be retried using the Restate invoker retry policy, which by default retries indefinitely.- Throws:
TerminalException
- See Also:
-
run
Likerun(String, Class, ThrowingSupplier)
without output.- Throws:
TerminalException
- See Also:
-
run
Likerun(Class, ThrowingSupplier)
without output.- Throws:
TerminalException
- See Also:
-
runAsync
default <T> DurableFuture<T> runAsync(String name, Class<T> clazz, ThrowingSupplier<T> action) throws TerminalException Execute a closure asynchronously. This is likerun(String, Class, ThrowingSupplier)
, but it returns aDurableFuture
that you can combine and select.// Fan-out var resultFutures = subTasks.stream() .map(task -> ctx.runAsync( task.description(), String.class, () -> task.execute() ) ) .toList(); // Await all of them DurableFuture.all(resultFutures).await(); // Fan in - Aggregate the results var results = resultFutures.stream() .map(future -> future.await()) .toList();
- Throws:
TerminalException
- See Also:
-
runAsync
default <T> DurableFuture<T> runAsync(String name, TypeTag<T> typeTag, ThrowingSupplier<T> action) throws TerminalException LikerunAsync(String, Class, ThrowingSupplier)
, but providing aTypeTag
.See
Context
for more details about serialization and deserialization.- Throws:
TerminalException
- See Also:
-
runAsync
default <T> DurableFuture<T> runAsync(String name, Class<T> clazz, RetryPolicy retryPolicy, ThrowingSupplier<T> action) throws TerminalException LikerunAsync(String, Class, ThrowingSupplier)
, but using a custom retry policy.When a retry policy is not specified, the
run
will be retried using the Restate invoker retry policy, which by default retries indefinitely.- Throws:
TerminalException
- See Also:
-
runAsync
<T> DurableFuture<T> runAsync(String name, TypeTag<T> typeTag, RetryPolicy retryPolicy, ThrowingSupplier<T> action) throws TerminalException LikerunAsync(String, TypeTag, ThrowingSupplier)
, but using a custom retry policy.When a retry policy is not specified, the
run
will be retried using the Restate invoker retry policy, which by default retries indefinitely.- Throws:
TerminalException
- See Also:
-
runAsync
default <T> DurableFuture<T> runAsync(TypeTag<T> typeTag, ThrowingSupplier<T> action) throws TerminalException LikerunAsync(String, TypeTag, ThrowingSupplier)
, without a name- Throws:
TerminalException
- See Also:
-
runAsync
default <T> DurableFuture<T> runAsync(Class<T> clazz, ThrowingSupplier<T> action) throws TerminalException LikerunAsync(String, Class, ThrowingSupplier)
, without a name- Throws:
TerminalException
- See Also:
-
runAsync
default DurableFuture<Void> runAsync(String name, RetryPolicy retryPolicy, ThrowingRunnable runnable) throws TerminalException LikerunAsync(String, Class, ThrowingSupplier)
, but without an output and using a custom retry policy.When a retry policy is not specified, the
run
will be retried using the Restate invoker retry policy, which by default retries indefinitely.- Throws:
TerminalException
- See Also:
-
runAsync
default DurableFuture<Void> runAsync(String name, ThrowingRunnable runnable) throws TerminalException LikerunAsync(String, Class, ThrowingSupplier)
without output.- Throws:
TerminalException
-
runAsync
LikerunAsync(String, Class, ThrowingSupplier)
without output.- Throws:
TerminalException
-
awakeable
Create anAwakeable
, addressable throughAwakeable.id()
.You can use this feature to implement external asynchronous systems interactions, for example you can send a Kafka record including the
Awakeable.id()
, and then let another service consume from Kafka the responses of given external system interaction by usingawakeableHandle(String)
.- Parameters:
clazz
- the response type to use for deserializing theAwakeable
result. When using generic types, useawakeable(TypeTag)
instead.- Returns:
- the
Awakeable
to await on. - See Also:
-
awakeable
Create anAwakeable
, addressable throughAwakeable.id()
.You can use this feature to implement external asynchronous systems interactions, for example you can send a Kafka record including the
Awakeable.id()
, and then let another service consume from Kafka the responses of given external system interaction by usingawakeableHandle(String)
. -
awakeableHandle
Create a newAwakeableHandle
for the provided identifier. You can use it toAwakeableHandle.resolve(TypeTag, Object)
orAwakeableHandle.reject(String)
the linkedAwakeable
.- See Also:
-
random
RestateRandom random()Returns a deterministic random.- See Also:
-