Skip to content

Commit b5ff868

Browse files
committed
wait for condition example
1 parent a5f4354 commit b5ff868

3 files changed

Lines changed: 83 additions & 43 deletions

File tree

examples/src/main/java/software/amazon/lambda/durable/examples/WaitExample.java

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@
33
package software.amazon.lambda.durable.examples;
44

55
import java.time.Duration;
6+
import java.util.stream.IntStream;
7+
68
import software.amazon.lambda.durable.DurableContext;
79
import software.amazon.lambda.durable.DurableFuture;
810
import software.amazon.lambda.durable.DurableHandler;
11+
import software.amazon.lambda.durable.config.MapConfig;
12+
import software.amazon.lambda.durable.config.WaitForConditionConfig;
13+
import software.amazon.lambda.durable.model.WaitForConditionResult;
914

1015
/**
1116
* Example demonstrating step execution with wait operations.
@@ -24,35 +29,43 @@ public class WaitExample extends DurableHandler<GreetingRequest, String> {
2429

2530
@Override
2631
public String handleRequest(GreetingRequest input, DurableContext context) {
27-
// Step 1: Start processing
28-
var started =
29-
context.step("start-processing", String.class, stepCtx -> "Started processing for " + input.getName());
30-
31-
// Wait 10 seconds
32-
context.wait(null, Duration.ofSeconds(10));
32+
var items =
33+
IntStream.range(0, 100).mapToObj(i -> input.getName() + "-" + i).toList();
3334

34-
// Step 2: Continue processing
35-
var continued = context.stepAsync("continue-processing", String.class, stepCtx -> {
36-
try {
37-
Thread.sleep(10000);
38-
} catch (InterruptedException e) {
39-
throw new RuntimeException(e);
40-
}
41-
return started + " - continued after 10s";
42-
});
35+
var config = MapConfig.builder().maxConcurrency(50).build();
4336

44-
// Wait at most seconds
45-
var wait5seconds = context.runInChildContextAsync("wait-5-seconds", String.class, ctx -> {
46-
ctx.wait("wait-5-seconds", Duration.ofSeconds(5));
37+
var result = context.map(
38+
"process-all",
39+
items,
40+
String.class,
41+
(item, index, ctx) -> {
42+
// Step 1: waitForCondition — fails twice, succeeds on 3rd attempt
43+
var conditionResult = ctx.waitForCondition(
44+
"condition-" + index,
45+
Integer.class,
46+
(callCount, stepCtx) -> {
47+
if (callCount % 3 == 0) {
48+
return WaitForConditionResult.stopPolling(callCount + 1);
49+
}
50+
return WaitForConditionResult.continuePolling(callCount + 1);
51+
},
52+
WaitForConditionConfig.<Integer>builder().initialState(1).build()
53+
);
4754

48-
return started + " - waited 5 seconds";
49-
});
55+
ctx.getLogger().info("Item {} condition resolved: {}", item, conditionResult);
5056

51-
var step2 = DurableFuture.anyOf(continued, wait5seconds);
57+
// Step 2: waitForCallback — wait for external approval
58+
var approved = ctx.waitForCallback("approval-" + index, String.class, (callbackId, stepCtx) -> {
59+
var command = String.format(
60+
"aws lambda send-durable-execution-callback-success --callback-id %s --result $(echo -n '\"approved\"' | base64)",
61+
callbackId);
62+
stepCtx.getLogger().info("To approve item '{}', run: {}", item, command);
63+
});
5264

53-
// Step 3: Complete
54-
var result = context.step("complete-processing", String.class, stepCtx -> step2 + " - completed after 5s more");
65+
return conditionResult + " -> " + approved;
66+
},
67+
config);
5568

56-
return result;
69+
return String.join(" | ", result.results());
5770
}
5871
}

examples/src/main/java/software/amazon/lambda/durable/examples/WaitForConditionExample.java

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,59 @@
44

55
import software.amazon.lambda.durable.DurableContext;
66
import software.amazon.lambda.durable.DurableHandler;
7+
import software.amazon.lambda.durable.config.MapConfig;
78
import software.amazon.lambda.durable.config.WaitForConditionConfig;
89
import software.amazon.lambda.durable.model.WaitForConditionResult;
910

11+
import java.util.concurrent.atomic.AtomicInteger;
12+
import java.util.stream.IntStream;
13+
1014
/**
1115
* Example demonstrating the waitForCondition operation.
1216
*
1317
* <p>This example simulates waiting for an order to ship, by repeatedly calling a check function.
1418
*/
15-
public class WaitForConditionExample extends DurableHandler<Integer, Integer> {
19+
public class WaitForConditionExample extends DurableHandler<GreetingRequest, String> {
1620

1721
@Override
18-
public Integer handleRequest(Integer input, DurableContext context) {
19-
// Poll the shipment status until the order is shipped.
20-
// The check function simulates an order shipment (0 -> 1 -> 2 -> 3 -> 4)
21-
return context.waitForCondition(
22-
"wait-for-shipment",
23-
Integer.class,
24-
(callCount, stepCtx) -> {
25-
// Simulate checking shipment status from an external service
26-
if (callCount >= 3) {
27-
// Order has shipped — stop polling
28-
return WaitForConditionResult.stopPolling(callCount + 1);
29-
}
30-
// Order still processing — continue polling
31-
return WaitForConditionResult.continuePolling(callCount + 1);
22+
public String handleRequest(GreetingRequest input, DurableContext context) {
23+
var items =
24+
IntStream.range(0, 100).mapToObj(i -> input.getName() + "-" + i).toList();
25+
26+
var config = MapConfig.builder().maxConcurrency(50).build();
27+
28+
var result = context.map(
29+
"process-all",
30+
items,
31+
String.class,
32+
(item, index, ctx) -> {
33+
// Step 1: waitForCondition — fails twice, succeeds on 3rd attempt
34+
var conditionResult = ctx.waitForCondition(
35+
"condition-" + index,
36+
Integer.class,
37+
(callCount, stepCtx) -> {
38+
if (callCount % 3 == 0) {
39+
return WaitForConditionResult.stopPolling(callCount + 1);
40+
}
41+
return WaitForConditionResult.continuePolling(callCount + 1);
42+
},
43+
WaitForConditionConfig.<Integer>builder().initialState(1).build()
44+
);
45+
46+
ctx.getLogger().info("Item {} condition resolved: {}", item, conditionResult);
47+
48+
// Step 2: waitForCallback — wait for external approval
49+
var approved = ctx.waitForCallback("approval-" + index, String.class, (callbackId, stepCtx) -> {
50+
var command = String.format(
51+
"aws lambda send-durable-execution-callback-success --callback-id %s --result $(echo -n '\"approved\"' | base64)",
52+
callbackId);
53+
stepCtx.getLogger().info("To approve item '{}', run: {}", item, command);
54+
});
55+
56+
return conditionResult + " -> " + approved;
3257
},
33-
WaitForConditionConfig.<Integer>builder().initialState(1).build()); // Order pending - initial status
58+
config);
59+
60+
return String.join(" | ", result.results());
3461
}
3562
}

examples/src/test/java/software/amazon/lambda/durable/examples/WaitForConditionExampleTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ class WaitForConditionExampleTest {
1313
@Test
1414
void testWaitForConditionExample() {
1515
var handler = new WaitForConditionExample();
16-
var runner = LocalDurableTestRunner.create(Integer.class, handler);
16+
var runner = LocalDurableTestRunner.create(GreetingRequest.class, handler);
1717

18-
var result = runner.runUntilComplete(123);
18+
var result = runner.runUntilComplete(new GreetingRequest());
1919

2020
assertEquals(ExecutionStatus.SUCCEEDED, result.getStatus());
21-
assertEquals(4, result.getResult(Integer.class));
21+
assertEquals("1234", result.getResult(String.class));
2222
}
2323
}

0 commit comments

Comments
 (0)