Skip to content

Latest commit

 

History

History
111 lines (80 loc) · 6.09 KB

File metadata and controls

111 lines (80 loc) · 6.09 KB

AWS Lambda Durable Execution SDK for .NET

Preview. Amazon.Lambda.DurableExecution is in active development (0.x). Public APIs may change before 1.0.

Amazon.Lambda.DurableExecution is the .NET SDK for building resilient, long-running AWS Lambda functions that automatically checkpoint progress and resume after failures. Workflows can run for up to one year, with charges only for active compute time.

Key Features

  • Automatic checkpointing — progress is saved after each step; failures resume from the last checkpoint.
  • Cost-effective waits — suspend execution for minutes, hours, or days without compute charges.
  • Configurable retries — built-in retry strategies with exponential backoff and jitter.
  • Replay safety — functions deterministically resume from checkpoints after interruptions.
  • Type safety — full generic type support for step results.
  • AOT-friendly — pluggable ILambdaSerializer so you can register SourceGeneratorLambdaJsonSerializer<TContext> for trimmed / Native AOT functions.

How It Works

Your handler delegates to DurableFunction.WrapAsync, which gives your workflow function an IDurableContext. The context is your interface to durable operations:

  • ctx.StepAsync — run code and checkpoint the result. (docs)
  • ctx.WaitAsync — suspend execution without compute charges. (docs)
  • ctx.WaitForConditionAsync — poll a check function until a condition is met, suspending between polls. (docs)
  • ctx.CreateCallbackAsync / ctx.WaitForCallbackAsync — wait for external events (approvals, webhooks). (docs)
  • ctx.RunInChildContextAsync — run an isolated child context with its own checkpoint log. (docs)
  • ctx.ParallelAsync — run independent branches concurrently and aggregate their results. (docs)
  • Every user Func receives a CancellationToken linking the caller's token with the SDK's workflow-shutdown signal. (docs)

Quick Start

Installation

dotnet add package Amazon.Lambda.DurableExecution

Your first durable function

Programming model: the preview only supports the executable programming model — your function is an executable assembly that hosts its own bootstrap loop and passes the serializer to the runtime in code. Class-library handlers on the managed runtime will be supported once the changes made to Amazon.Lambda.RuntimeSupport to support durable functions has been deployed to the managed runtime. This README will be updated then.

A complete order-processing workflow with two steps and a wait, deployed as an executable assembly on the dotnet10 runtime. Main builds a LambdaBootstrap with your handler and an ILambdaSerializer, and DurableFunction.WrapAsync uses that serializer to checkpoint step inputs and outputs.

using Amazon.Lambda.Core;
using Amazon.Lambda.DurableExecution;
using Amazon.Lambda.RuntimeSupport;
using Amazon.Lambda.Serialization.SystemTextJson;

namespace OrderProcessor;

public class OrderProcessor
{
    public static async Task Main()
    {
        var handler = new OrderProcessor();
        var serializer = new DefaultLambdaJsonSerializer();
        using var wrapper = HandlerWrapper.GetHandlerWrapper<DurableExecutionInvocationInput, DurableExecutionInvocationOutput>(
            handler.Handler, serializer);
        using var bootstrap = new LambdaBootstrap(wrapper);
        await bootstrap.RunAsync();
    }

    public Task<DurableExecutionInvocationOutput> Handler(
        DurableExecutionInvocationInput input, ILambdaContext context)
        => DurableFunction.WrapAsync<Order, OrderResult>(Workflow, input, context);

    private async Task<OrderResult> Workflow(Order order, IDurableContext ctx)
    {
        var reservation = await ctx.StepAsync(
            async (_, ct) => await InventoryService.ReserveAsync(order.Items, ct),
            name: "reserve-inventory");

        var payment = await ctx.StepAsync(
            async (_, ct) => await PaymentService.ChargeAsync(order.PaymentMethod, order.Total, ct),
            name: "process-payment");

        await ctx.WaitAsync(TimeSpan.FromHours(2), name: "warehouse-processing");

        var shipment = await ctx.StepAsync(
            async (_, ct) => await ShippingService.ShipAsync(reservation, order.Address, ct),
            name: "confirm-shipment");

        return new OrderResult(order.Id, shipment.TrackingNumber);
    }
}

public record Order(string Id, IReadOnlyList<OrderItem> Items, PaymentMethod PaymentMethod, decimal Total, Address Address);
public record OrderResult(string OrderId, string TrackingNumber);

For AOT or trim-friendly serialization, swap DefaultLambdaJsonSerializer for SourceGeneratorLambdaJsonSerializer<TContext> and register your JsonSerializerContext.

Documentation

Core operations

  • Steps — execute code with automatic checkpointing, retry strategies, and at-least/at-most-once semantics.
  • Wait — pause execution without compute charges.
  • Wait For Condition — poll until a condition is met, suspending between polls with a configurable wait strategy.
  • Callbacks — wait for external systems to respond.
  • Child Contexts — group related operations into isolated, checkpointed units.
  • Parallel — fan out independent branches concurrently with configurable concurrency and completion policies.

Examples

End-to-end test functions (each paired with an integration test) live under Libraries/test/Amazon.Lambda.DurableExecution.IntegrationTests/TestFunctions/.

Related SDKs