Status: Accepted
Date: 2025-12-29
Durable functions need to suspend execution immediately at suspension points (wait, callback, retry). The system must return PENDING status to Lambda without waiting for the handler to complete.
public String handleRequest(MyInput input, DurableContext context) {
var result1 = context.step("step1", stepCtx -> "first");
context.wait(null, Duration.ofHours(1)); // Should suspend HERE
var result2 = context.step("step2", stepCtx -> "second"); // Don't wait for this
return result1 + result2;
}Run the handler in a background thread and race two futures:
var handlerFuture = CompletableFuture.supplyAsync(stepCtx -> handler.apply(input, context), executor);
var suspendFuture = executionManager.getSuspendExecutionFuture();
CompletableFuture.anyOf(handlerFuture, suspendFuture).join();
if (suspendFuture.isDone()) {
return DurableExecutionOutput.pending();
}try {
O result = handler.apply(input, context);
return DurableExecutionOutput.success(result);
} catch (SuspendExecutionException e) {
return DurableExecutionOutput.pending();
}Rejected because:
- Users can catch and suppress the exception
- Requires two-level exception handling (operation wants suspend vs. ExecutionManager confirms suspend)
- Exceptions for control flow is an anti-pattern
Positive:
- Immediate suspension without waiting for handler completion
- Clean separation: suspension decision is in ExecutionManager, not scattered in operations
- Users cannot accidentally suppress suspension
Negative:
- More complex threading model
- Requires thread tracking in ExecutionManager