runBlock

abstract suspend fun <T> runBlock(serde: Serde<T>, name: String = "", block: suspend () -> T): T

Execute a non-deterministic 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. Use this feature if you want to perform non-deterministic operations.

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.

Error handling

Errors occurring within this closure won't be propagated to the caller, unless they are TerminalException. Consider the following code:

// Bad usage of try-catch outside the runBlock
try {
ctx.runBlock {
throw IllegalStateException();
};
} catch (e: IllegalStateException) {
// 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 runBlock
try {
ctx.runBlock {
throw TerminalException("my error");
};
} catch (e: TerminalException) {
// This is invoked
}

To propagate failures to the run call-site, make sure to wrap them in TerminalException.

Return

value of the runBlock operation.

Parameters

serde

the type tag of the return value, used to serialize/deserialize it.

name

the name of the side effect.

block

closure to execute.

T

type of the return value.


abstract suspend fun <T> runBlock(serde: Serde<T>, name: String = "", retryPolicy: RetryPolicy? = null, block: suspend () -> T): T

Like runBlock, but using a custom retry policy.

When a retry policy is not specified, the runBlock will be retried using the Restate invoker retry policy, which by default retries indefinitely.