Skip to content

Latest commit

 

History

History
97 lines (74 loc) · 5.07 KB

configuration.md

File metadata and controls

97 lines (74 loc) · 5.07 KB

Configuration

Customize SDK behavior by overriding createConfiguration() in your handler:

public class OrderProcessor extends DurableHandler<Order, OrderResult> {

    @Override
    protected DurableConfig createConfiguration() {
        // Custom Lambda client with connection pooling
        var lambdaClientBuilder = LambdaClient.builder()
            .httpClient(ApacheHttpClient.builder()
                .maxConnections(50)
                .connectionTimeout(Duration.ofSeconds(30))
                .build());

        return DurableConfig.builder()
            .withLambdaClientBuilder(lambdaClientBuilder)
            .withSerDes(new MyCustomSerDes())           // Custom serialization
            .withExecutorService(Executors.newFixedThreadPool(10))  // Custom thread pool
            .withLoggerConfig(LoggerConfig.withReplayLogging())     // Enable replay logs
            .build();
    }

    @Override
    protected OrderResult handleRequest(Order order, DurableContext ctx) {
        // Your handler logic
    }
}
Option Description Default
withLambdaClientBuilder() Custom AWS Lambda client Auto-configured Lambda client
withSerDes() Serializer for step results Jackson with default settings
withExecutorService() Thread pool for user-defined operations Cached daemon thread pool
withLoggerConfig() Logger behavior configuration Suppress logs during replay
withPollingStrategy() Backend polling strategy Exponential backoff: 1s base, 2x rate, FULL jitter, 10s max
withCheckpointDelay() How often the SDK checkpoints updates Duration.ofSeconds(0) (as soon as possible)

The withExecutorService() option configures the thread pool used for running user-defined operations. Internal SDK coordination (checkpoint batching, polling) runs on an SDK-managed thread pool.

Dynamic plugin loading

Dynamic plugin loading is an opt-in alternative to registering plugins in application code. Put provider JARs on the application class path, then set DURABLE_EXECUTION_PLUGINS to an ordered, comma-separated list of provider names:

DURABLE_EXECUTION_PLUGINS=otel-invocation,com.example.audit

When the variable is unset or blank, the SDK does not perform provider discovery. During DurableConfig construction, the SDK uses ServiceLoader and the thread context class loader to find DurableExecutionPluginProvider implementations. Only named providers create plugins.

Dynamically loaded plugins run first in the order listed in DURABLE_EXECUTION_PLUGINS. Plugins registered through withPlugins(...) follow in configuration order. Both sources are additive: if the same plugin is selected dynamically and registered explicitly, both factories are registered and each produces an instance that receives lifecycle hooks. Duplicate configured provider names, duplicate discovered provider names, missing providers, provider discovery failures, and selected providers that were built against an older SDK and do not implement createPlugin(InvocationInfo) stop configuration with an IllegalStateException.

To distribute a provider in a Lambda layer, package its JAR under java/lib:

my-plugin-layer.zip
`-- java
    `-- lib
        `-- my-durable-plugin.jar

The provider JAR must contain:

META-INF/services/software.amazon.lambda.durable.plugin.DurableExecutionPluginProvider

The service file contains the provider implementation class name. A provider is itself the per-invocation plugin factory: the SDK calls createPlugin(InvocationInfo) once per Lambda invocation and drops the returned instance when that invocation returns, so the instance can hold its invocation's state in plain fields. A minimal provider looks like:

public final class AuditPluginProvider implements DurableExecutionPluginProvider {
    @Override
    public String getName() {
        return "com.example.audit";
    }

    @Override
    public DurableExecutionPlugin createPlugin(InvocationInfo invocationInfo) {
        return new AuditPlugin(invocationInfo.durableExecutionArn());
    }
}

Provider-specific settings can use namespaced environment variables. If an application shades provider JARs into one artifact, its build must preserve and merge META-INF/services entries.

Filesystem serialization

The SDK includes Filesystem SerDes, which provides ALWAYS and OVERFLOW modes, URI/hash paths, delegate serializers, and previews. Configure it per operation with serDes(...); keep the global serializer for normal Lambda input/output. It requires a durable shared mount and external file retention.

Custom serializers can override serialize(value, SerDesContext) and deserialize(data, typeToken, SerDesContext) to receive stable execution/entity identity. Existing implementations inherit defaults that call the original methods.