Remix.run Logo
skrtskrt 3 hours ago

How do “stream over an open connection” and things like “sleep for months” play together?

Naively without digging into the code I would look at a “streaming over an open connection” as likely to strictly more brittle.

stsffap 3 hours ago | parent | next [-]

The way it works is that Restate supports suspending workflows that sleep for months and later (once the sleep finishes) resumes them at exactly this point. Technically, this is the same process as resuming a crashed workflow.

While the workflow is actively doing work (like calling other services, accessing state or interacting with external services, for example) the server is connected to the workflow deployment via a low-latency bidirectional streaming connection to receive and acknowledge progress that the workflow makes. That way the workflow can finish as fast as possible.

A nice side effect of this model is that you can co-locate your workflow with expensive resources, such as a sandbox, which should be used by all durable actions that the workflow executes. The reason this works is because Restate can inline durable steps (what would be modeled in Temporal as activities, I believe).

gvdongen 3 hours ago | parent | prev | next [-]

If a handler starts a sleep/human approval/RPC call, or so, then this timer/promise is persisted in Restate's journal. Restate does the waiting. The handler process itself can suspend (e.g. on a serverless function), and the bidirectional connection is closed. Once the timer fires/approval comes in, Restate re-invokes the service with the journal of previously completed steps, and the service can replay to the exact point in the code where it suspended and continue from there. Restate is like a DB for journals, so you can sleep for as long as needed, also months.

So you have fast persistence of events while a handler can make progress, and suspensions while waiting.

sewen 2 hours ago | parent | prev [-]

I guess the confusion is that it doesn't have to be one single persistent stream.

While the durable function does fast work and adds steps, it pushes it through a stream. When a wait point comes, it closes and replays on resumption (typical durable execution style).

That gives you the best of both worlds: same long-running workflows with long sleets and suspensions, but also ability to add steps with few ms overhead only.