Is suspension a primitive or a trick?
Resonate is addressing the problem of suspension by pinning the answer to a protocol instead of a runtime.
Have you read this? Hanging Promises for Control Flow.
So, if I understand it correctly, you’re inside a serverless function. You hit a step you can’t finish in this invocation. You need to get the user’s async function off the stack without throwing — because user try/catch might swallow the signal. So you await a promise that never resolves. Function suspends, process gets torn down, GC cleans up the frame, fresh invocation replays from the top using a memoization map of finished steps.
Clever, though isn’t this a workaround for a problem that only exists because suspension isn’t a first-class thing the runtime owns?
Seems like the whole maneuver leans on a property of the language’s runtime, where each language would require its own version of the trick with its own caveats.
As you know I work Resonate HQ and we bet (well, Dominik Tornow bet) that suspension shouldn’t be a clever thing the runtime sneaks past user code — it should be a protocol.
Coincidentally enough, the protocol calls for a durable promise that lives outside any single process, or any single language.
When a function awaits a durable promise, the runtime parks the computation. Promise resolves — same process, different process, one that doesn’t exist yet — computation comes back. No exception to dodge, no GC trick to lean on. The await (or in the current Resonate Typescript SDK version its yield) means what it says.
If that’s right, the hanging-promise technique is a great answer inside one language’s constraints, but Resonate is making the same problem moot one layer down by pinning the answer to a protocol instead of a runtime.
If you think I’ve got something backwards, tell me.


