Idempotency
How does Reboot handle idempotency?
Calls from code generated for React will use idempotency keys by
default. Within Reboot, you only need to manually handle idempotency
if you're trying to retry things manually in a client (using
ExternalContext
) or when writing a workflow
method (using
WorkflowContext
, which is automatically retried).
If you're only trying to call a method of a specific state once
using your context, you can call that method after
using the fluent .idempotently()
method, e.g.,
foo.idempotently().Method(context)
. If you need to call the same
method on a state more than once, including when you're doing manual
retries, then you can specify an idempotency "alias" to
distinguish each call, for example:
- Python
- TypeScript
bank = Bank.lookup(SINGLETON_BANK_ID)
await bank.idempotently().SignUp(
context,
customer_name="Initial User",
)
await Bank.construct({ id: SINGLETON_BANK_ID })
.idempotently()
.signUp(context, { customerName: "Initial User" });
When you don't pass anything to .idempotently()
, or when you just
pass a string alias, Reboot will deterministically generate an
idempotency key for you. You can also manually pass an
idempotency key by calling .idempotently(key=...)
.
Why require idempotency?
Idempotency protects your system and your users against insidious distributed system bugs. Temporary network and server outages are always a risk when coordinating multiple machines, so it is often necessary to retry requests - opening up the possibility for a server to receive multiple requests when only one call was intended.
Idempotency does come with some storage overhead, but the protection it gives in return is a fundamental way in which Reboot keeps your system safe.