ChildContextExample.java
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.examples.child;
import java.time.Duration;
import software.amazon.lambda.durable.DurableContext;
import software.amazon.lambda.durable.DurableFuture;
import software.amazon.lambda.durable.DurableHandler;
import software.amazon.lambda.durable.examples.types.GreetingRequest;
/**
* Example demonstrating child context workflows with the Durable Execution SDK.
*
* <p>This handler runs three concurrent child contexts using {@code runInChildContextAsync}:
*
* <ol>
* <li><b>Order validation</b> — performs a step then suspends via {@code wait()} before completing
* <li><b>Inventory check</b> — performs a step then suspends via {@code wait()} before completing
* <li><b>Shipping estimate</b> — nests another child context inside it to demonstrate hierarchical contexts
* </ol>
*
* <p>All three child contexts run concurrently. Results are collected with {@link DurableFuture#allOf} and combined
* into a summary string.
*/
public class ChildContextExample extends DurableHandler<GreetingRequest, String> {
@Override
public String handleRequest(GreetingRequest input, DurableContext context) {
var name = input.getName();
context.getLogger().info("Starting child context workflow for {}", name);
// Child context 1: Order validation — step + wait + step
var orderFuture = context.runInChildContextAsync("order-validation", String.class, child -> {
var prepared = child.step("prepare-order", String.class, stepCtx -> "Order for " + name);
child.getLogger().info("Order prepared, waiting for validation");
child.wait("validation-delay", Duration.ofSeconds(5));
return child.step("validate-order", String.class, stepCtx -> prepared + " [validated]");
});
// Child context 2: Inventory check — step + wait + step
var inventoryFuture = context.runInChildContextAsync("inventory-check", String.class, child -> {
var stock = child.step("check-stock", String.class, stepCtx -> "Stock available for " + name);
child.getLogger().info("Stock checked, waiting for confirmation");
child.wait("confirmation-delay", Duration.ofSeconds(3));
return child.step("confirm-inventory", String.class, stepCtx -> stock + " [confirmed]");
});
// Child context 3: Shipping estimate — nests a child context inside it
var shippingFuture = context.runInChildContextAsync("shipping-estimate", String.class, child -> {
var baseRate = child.step("calculate-base-rate", String.class, stepCtx -> "Base rate for " + name);
// Nested child context: calculate regional adjustment
var adjustment = child.runInChildContext(
"regional-adjustment",
String.class,
nested ->
nested.step("lookup-region", String.class, stepCtx -> baseRate + " + regional adjustment"));
return child.step("finalize-shipping", String.class, stepCtx -> adjustment + " [shipping ready]");
});
// Collect all results using allOf
context.getLogger().info("Waiting for all child contexts to complete");
var results = DurableFuture.allOf(orderFuture, inventoryFuture, shippingFuture);
// Combine into summary
var summary = String.join(" | ", results);
context.getLogger().info("All child contexts complete: {}", summary);
return summary;
}
}