Add parallel execution capability to the AWS Lambda Durable Execution SDK, allowing multiple branches to run concurrently within a single durable function execution.
try (var parallelContext = ctx.parallel(ParallelConfig.builder().build())) {
DurableFuture<Boolean> task1 = parallelContext.branch("validate", Boolean.class, branchContext -> validate());
DurableFuture<String> task2 = parallelContext.branch("process", String.class, branchContext -> process());
parallelContext.join(); // Wait for completion based on config
// Access results
Boolean validated = task1.get();
String processed = task2.get();
}Configuration object controlling parallel execution behavior:
ParallelConfig config = ParallelConfig.builder()
.maxConcurrency(5) // Max branches running simultaneously
.minSuccessful(3) // Minimum successful branches required (-1 = all)
.toleratedFailureCount(2) // Max failures before stopping execution
.build();Configuration Rules:
maxConcurrency: Controls resource usage, prevents overwhelming the systemminSuccessful: Enables "best effort" scenarios where not all branches need to succeedtoleratedFailureCount: Fail-fast behavior when too many branches fail
Manages the lifecycle of parallel branches:
public class ParallelContext implements AutoCloseable {
// Create branches
public <T> DurableFuture<T> branch(String name, Class<T> resultType, Function<DurableContext, T> func);
public <T> DurableFuture<T> branch(String name, TypeToken<T> resultType, Function<DurableContext, T> func);
// Wait for completion
public void join();
// AutoCloseable ensures join() is called
public void close();
}Add single method to existing DurableContext:
public ParallelContext parallel(ParallelConfig config);Each parallel branch will be implemented as a ChildContextOperation:
- Isolation: Each branch has its own checkpoint log
- Replay Safety: Branches replay independently
- Error Handling: Branch failures don't affect other branches directly
- Branch Registration:
branch()calls createChildContextOperationinstances but don't execute immediately - Execution Start:
join()triggers execution of branches respectingmaxConcurrency - Concurrency Control: Use a queue to manage pending branches when
maxConcurrencyis reached - Completion Logic: Monitor success/failure counts against configuration thresholds
- Result Collection: Return results via
DurableFutureinstances
Branch-Level Failures:
- Individual branch failures are captured in their respective
DurableFuture - Don't immediately fail the entire parallel operation
- Count towards
failureCountfor threshold checking
Parallel-Level Failures:
- Exceed
toleratedFailureCount: Stop starting new branches, wait for running ones - Insufficient
minSuccessful: ThrowParallelExecutionExceptionafter all branches complete - Configuration validation errors: Fail immediately
- Pros: Reuses existing isolation and checkpointing logic
- Cons: Each branch has overhead of a separate child context
- Decision: Acceptable trade-off for clean isolation and replay safety
- Chosen: Lazy execution (branches start only on
join()) - Rationale: Allows all branches to be registered before execution starts, enabling better concurrency planning
- Purpose: Ensures
join()is called even if user forgets - Behavior: If
close()is called beforejoin(), automatically calljoin()
- Validate at
ParallelConfig.build()time:maxConcurrency > 0minSuccessful >= -1(where -1 means "all")toleratedFailureCount >= 0minSuccessful + toleratedFailureCount <= total branches(validated at runtime)
ParallelConfig.java- Configuration builderParallelContext.java- User-facing parallel contextoperation/ParallelOperation.java- Core execution logicexception/ParallelExecutionException.java- Parallel-specific exceptions
DurableContext.java- Addparallel()methodDurableFuture.java- Ensure compatibility with parallel results (likely no changes needed)
ParallelConfigTest- Configuration validationParallelOperationTest- Core execution logic with mocked child contexts
- Success scenarios with various configurations
- Failure scenarios (exceeding thresholds)
- Concurrency limits
- Replay behavior
ParallelExample.javain examples module- Demonstrate common patterns and error handling