Restate uses an execution log to replay operations after failures and suspensions. Non-deterministic operations (database calls, HTTP requests, UUID generation) must be wrapped to ensure deterministic replay.

Run

Use Run to safely wrap any non-deterministic operation, like HTTP calls or database responses, and have Restate store its result in the execution log.
result, err := restate.Run(ctx, func(ctx restate.RunContext) (string, error) {
  return doDbRequest()
})
if err != nil {
  return err
}
Note that inside Run, you cannot use the Restate context (e.g., get, sleep, or nested Run). You should only use methods available on the RunContext provided to your function.

Deterministic randoms

The SDK provides deterministic helpers for random values — seeded by the invocation ID — so they return the same result on retries.

UUIDs

To generate stable UUIDs for things like idempotency keys:
uuid := restate.Rand(ctx).UUID()
Do not use this in cryptographic contexts.

Random numbers

Methods exist on restate.Rand(ctx) for generating float64 and uint64, or otherwise restate.Rand(ctx).Source() can be provided to math/rand/v2 as a source for any random operation:
randomInt := restate.Rand(ctx).Uint64()
randomFloat := restate.Rand(ctx).Float64()
randomSource := rand.New(restate.Rand(ctx).Source())