Durable Execution
Restate provides resilience for applications via its Durable Execution mechanism.
A Durable Execution engine tracks code execution to enable recovery of partial progress in case of failures.
Restate implements Durable Execution by keeping track of the progress of execution in a central, persisted log that can be replayed in case of failures. Restate uses a combination of a server and SDK libraries to provide durable execution.
The SDKs are responsible for tracking the progress of the execution and sending it to the runtime.
The Restate server is responsible for storing the progress in a durable log and triggering retries in case of failures. When the Restate server triggers a retry, it sends the progress log to the SDK, which replays the log to continue the execution from where it left off.
State
cartService: Joe - cart=[]
Journals
addTicket ( Joe, seat2B )
reserve ( seat2B )
This animation shows you how durable execution takes place in Restate. The animation shows a ticket reservation platform for a theatre, where users can add tickets to their cart. Tickets can only be reserved by a single user. The application consists of two components: the CartObject and the TicketObject.
async function addTicket(ctx, ticketId){
const success = await ctx
.objectClient(ticketManager, ticketId)
.reserve();
if (success) {
const cart = await ctx.get("cart");
ctx.set("cart", cart.push(ticketId));
}
return success;
}
Journal:
state(cart=[])
{ seat2B }
{ success }
cart=[]
cart=[seat2B]
{ success }
async function reserve(ctx, ticketId){
...
return success;
}
Journal:
state()
{ success }
In case of a failure (e.g. timeout, infrastructure crash, network glitch), Restate will retry the execution by invoking the handler again and sending over the latest version of the journal. The handler then starts executing again and whenever it encounters an action on the Restate context, it will skip execution and will inject the response it finds in the journal. This way the handler can recover up to the point where it crashed.