Journaling Results
Restate uses an execution log for replay after failures and suspensions. This means that non-deterministic results (e.g. database responses, UUID generation) need to be stored in the execution log, so they can be replayed.
You can use ctx.run
to do this.
Here is an example of a database request for which the string response is stored in Restate:
async def do_db_request():# ... implement ...return "my_result"result = await ctx.run("database request", do_db_request)
You cannot use the Restate context within ctx.run
.
This includes actions such as getting state, calling another service, and nesting other journaled actions.
You can return any payload that can be serialized with bytes(json.dumps(obj), "utf-8")
and deserialized with json.loads(buf)
.
If not, you need to specify a custom serializer.
Always immediately await ctx.run
, before doing any other context calls.
If not, you might bump into non-determinism errors during replay,
because the journaled result can get interleaved with the other context calls in the journal in a non-deterministic way.
Failures in ctx.run
have the same semantics as failures in the rest of your handler code.
By default, the ctx.run
function is retried infinitely on failure, unless you specify differently in the retry policy (see below) or throw a TerminalError
.
Run-block Retry Policies
You can configure the retry policy for the ctx.run
block:
try:await ctx.run("write", lambda: write_to_other_system(),# Max number of retry attempts to complete the action.max_attempts=3,# Max duration for retrying, across all retries.max_retry_duration=timedelta(seconds=10))except TerminalError as err:# Handle the terminal error after retries exhausted# For example, undo previous actions (see sagas guide) and# propagate the error back to the callerraise err
This way you can override the default retry behavior of your Restate service for specific operations.
If you set a maximum number of attempts, then the ctx.run
block will fail with a TerminalError
once the retries are exhausted.
Have a look at the error handling docs and Sagas guide to learn how to handle these.