Workloads
Workflows
Run durable multi-step jobs that survive restarts and scale to zero while they sleep.
Prefer to read code? Clone the example repository. View on GitHub
Example generated code
import { Hono } from "hono";
import { actor, setup } from "rivetkit";
import { workflow } from "rivetkit/workflow";
type Status = "placed" | "paid" | "shipped" | "delivered";
// The workflow runs when the actor is created. Each step is durable, so the
// actor can sleep, scale to zero, and resume exactly where it left off.
const order = actor({
state: { status: "placed" as Status },
actions: {
status: (c) => c.state.status,
},
run: workflow(async (wf) => {
await wf.step("charge", async (c) => {
c.state.status = "paid";
});
await wf.step("ship", async (c) => {
c.state.status = "shipped";
});
await wf.sleep("in transit", 2_000);
await wf.step("deliver", async (c) => {
c.state.status = "delivered";
});
}),
});
export const registry = setup({ use: { order } });
const app = new Hono();
app.all("/api/rivet/*", (c) => registry.handler(c.req.raw));
app.get("/", (c) =>
c.json({ message: "Use the RivetKit client to read orders." }),
);
export default app;
Deploy and connect
Deploy the app, then connect to its actors from your own system:
const client = createClient<typeof registry>({
endpoint: deployment.endpoint,
namespace: deployment.namespace,
poolName: deployment.pool,
token: deployment.token,
});
// Creating the actor starts its workflow. Poll until it finishes.
const order = client.order.getOrCreate(["order-1042"]);
let status = await order.status();
while (status !== "delivered") {
console.log("status", status);
await new Promise((resolve) => setTimeout(resolve, 500));
status = await order.status();
}
console.log("status", status);
See Workflows in Rivet Actors for steps, loops, queues, and error handling.