DurableFunction
Source:
src/AWS/Lambda/DurableFunction.ts
An AWS Lambda Durable Function — a code-first, replay-based orchestrator
that IS a durable Lambda Function. AWS.Lambda.DurableFunction is a
wrapper of Function: it owns the underlying Lambda function,
configures its DurableConfig at CreateFunction (durability is a
create-time property — a DurableFunction is always durable), registers the
durable-execution listener on the owned entrypoint, self-binds the
checkpoint-protocol IAM (lambda:CheckpointDurableExecution,
lambda:GetDurableExecutionState) onto the execution role, and vendors the
open-source @aws/durable-execution-sdk-js into the artifact (install it
in your project: npm i @aws/durable-execution-sdk-js).
Executions progress by checkpoint + replay: a Durable.sleep or
Durable.waitForCallback suspends the execution with zero compute billed
until Lambda re-invokes the same function version to resume, and completed
Durable.steps replay from the checkpoint log without re-executing.
Every invocation of a durable function arrives as the durable-execution
envelope, so a DurableFunction has no HTTP surface (url is disabled) —
it does one thing: run durable orchestrations. Reusing a logical id
between a plain Function and a DurableFunction replaces the physical
function (DurableConfig cannot be flipped in place).
Defining a Durable Function
Section titled “Defining a Durable Function”Class form with steps and a durable sleep
export class OrderFlow extends AWS.Lambda.DurableFunction<OrderFlow>()( "OrderFlow", { main: import.meta.url, executionTimeout: "1 hour", retentionPeriod: "7 days", }, Effect.gen(function* () { // init: resolve typed binding clients (IAM lands on this function's role) const putItem = yield* AWS.DynamoDB.PutItem(table);
return Effect.fn(function* (input: { orderId: string }) { const reserved = yield* AWS.Lambda.Durable.step( "reserve", putItem({ Item: { pk: { S: input.orderId } } }).pipe(Effect.orDie), { retry: { limit: 3, delay: "5 seconds" } }, ); yield* AWS.Lambda.Durable.sleep("cooldown", "10 minutes"); return { orderId: input.orderId, reserved }; }); }),) {}Tag + default export (entrypoint form)
// order-flow.ts — `main` points at this moduleexport class OrderFlow extends AWS.Lambda.DurableFunction<OrderFlow>()( "OrderFlow",) {}
export default OrderFlow.make( { main: import.meta.url, executionTimeout: "1 hour" }, Effect.gen(function* () { return Effect.fn(function* (input: { orderId: string }) { return yield* AWS.Lambda.Durable.step("work", doWork(input)); }); }),);Inline effect form
const flow = yield* AWS.Lambda.DurableFunction( "OrderFlow", { main: "./src/order-flow.ts" }, Effect.gen(function* () { return Effect.fn(function* (input: { orderId: string }) { return yield* AWS.Lambda.Durable.step("work", doWork(input)); }); }),);Starting and Monitoring Executions
Section titled “Starting and Monitoring Executions”Starting an execution
const orders = yield* OrderFlow;const ref = yield* orders.start({ name: "order-123", // idempotent start params: { orderId: "123" },});Checking status
const execution = yield* orders.get(ref.executionArn!);// execution.Status: "RUNNING" | "SUCCEEDED" | "FAILED" | ...External Callbacks
Section titled “External Callbacks”const approval = yield* AWS.Lambda.Durable.waitForCallback<{ ok: boolean }>( "approve", (callbackId) => storeCallbackId(callbackId), { timeout: "1 day" },);