This chapter covers
- Short-running versus long-running processes
- Failure-free definitions
- Failure-tolerant executions
- Sagas versus durable executions
Durable executions, an emerging concept in software engineering, are to distributed systems what transactions are to databases: an abstraction concealing the possibility of failure.
11.1 The pitfalls of partial executions
In the presence of partial failure, even the most basic rules for reasoning about computations do not hold. —Andrew P. Black, Vincent Cremet, Rachid Guerraoui, and Martin Odersky, “An Equational Theory for Transactions,” (https://mng.bz/158j)
Imagine a user registering for a streaming platform for video or music streaming. During the registration process, the platform handles the user’s credit card payment and then grants access to its content library. The following listing displays the steps involved in the signup function.
Listing 11.1 User signup function
async function signup(user) { const charge = await Payment.create({ ... });#1 const account = await Account.create({ ... }); }
At first glance, the function may appear to be fine. On closer inspection, however, we notice a problem: the function handles only the happy path, naively ignoring the possibility of failure. If the function crashes after charging the credit card but before updating the database—that is, it executes partially—the user will be charged but will not have access to the content.