Outside Runtime Boundaries
In software engineering, async • await has fundamentally changed the way we develop asynchronous and concurrent applications. Async • await enables us to develop asynchronous, concurrent functions by writing synchronous, serial looking code.
We raised the abstraction level and improved the developer experience by removing (as in hiding) what we do not care about. Can we further elevate async • await to be the foundation of reliable asynchronous and concurrent applications?
Durable Async • Await
Consider this scenario: you are running an async function, waiting on a promise to settle, when the runtime e.g. the JavaScript engine, crashes.
Traditionally, in a volatile environment, you will lose both the function and the promise, forcing you to run some kind of recovery, often a retry, when the system comes back online.
What if you could simply pick up where you left off?
This is the essence of durable async • await. Durable functions and durable promises outlive the runtime. This guarantees that the operation will eventually complete, regardless of runtime interruptions.
Execution Runtime Separation
Durable async • await hinges on the idea of separating execution from the runtime. Traditionally, execution state is intrinsically tied to its runtime.
For durable async • await, its execution state is externalized. If the runtime crashes, this external state allows functions and promises to be rehydrated on a different runtime — continuing the execution.
Benefits
Once again, we raised the abstraction level and improved the developer experience by removing (as in hiding) what we do not care about. This time, we removed the need for crash detection and mitigation, guaranteeing eventual completion.
And completeness guarantees render many complex problems trivial.