RetryWaitForCallbackExample.java
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.examples.callback;
import java.time.Duration;
import software.amazon.lambda.durable.DurableContext;
import software.amazon.lambda.durable.DurableHandler;
import software.amazon.lambda.durable.config.WithRetryConfig;
import software.amazon.lambda.durable.examples.types.ApprovalRequest;
import software.amazon.lambda.durable.retry.RetryDecision;
/**
* Example demonstrating {@code context.withRetry} with {@code context.waitForCallback}.
*
* <p>Submits an approval request to an external system via a callback. If the callback fails (e.g., the external system
* rejects the request), the helper retries the entire waitForCallback cycle — creating a fresh callback with a new ID
* each time.
*
* <p>Each attempt uses a unique callback name ({@code "approval-1"}, {@code "approval-2"}, etc.) so the execution
* history stays clean and replay-safe. A {@code null} name is used, so attempts are grouped under a default-named child
* context.
*/
public class RetryWaitForCallbackExample extends DurableHandler<ApprovalRequest, String> {
private static final int MAX_ATTEMPTS = 3;
@Override
public String handleRequest(ApprovalRequest input, DurableContext context) {
// Step 1: Prepare the approval request
var prepared = context.step(
"prepare",
String.class,
stepCtx -> "Approval for: " + input.description() + " ($" + input.amount() + ")");
// Step 2: waitForCallback with retry — if the external system fails, try again with a fresh callback
var approvalResult = context.withRetry(
null,
(attempt, ctx) -> ctx.waitForCallback(
"approval-" + attempt, String.class, (callbackId, stepCtx) -> stepCtx.getLogger()
.info("Attempt {}: sending callback {} to approval system", attempt, callbackId)),
WithRetryConfig.builder()
.retryStrategy((error, attempt) -> attempt < MAX_ATTEMPTS
? RetryDecision.retry(Duration.ofSeconds(2))
: RetryDecision.fail())
.build());
// Step 3: Process the result
return context.step("process-result", String.class, stepCtx -> prepared + " - Result: " + approvalResult);
}
}