Skip to content

Commit 6218c96

Browse files
authored
add stepCtx to all step examples and docs (#164)
1 parent 4be5833 commit 6218c96

40 files changed

Lines changed: 204 additions & 194 deletions

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ examples/src/test/ # Customer-facing examples + cloud tests
142142
@Test
143143
void stepReturnsResultOnReplay() {
144144
var context = createTestContext(completedOperations);
145-
var result = context.step("test", String.class, () -> "new");
145+
var result = context.step("test", String.class, stepCtx -> "new");
146146
assertEquals("cached", result); // Returns cached, doesn't re-execute
147147
}
148148
```

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,18 @@ public class OrderProcessor extends DurableHandler<Order, OrderResult> {
5050
protected OrderResult handleRequest(Order order, DurableContext ctx) {
5151
// Step 1: Validate and reserve inventory
5252
var reservation = ctx.step("reserve-inventory", Reservation.class,
53-
() -> inventoryService.reserve(order.getItems()));
53+
stepCtx -> inventoryService.reserve(order.getItems()));
5454

5555
// Step 2: Process payment
5656
var payment = ctx.step("process-payment", Payment.class,
57-
() -> paymentService.charge(order.getPaymentMethod(), order.getTotal()));
57+
stepCtx -> paymentService.charge(order.getPaymentMethod(), order.getTotal()));
5858

5959
// Wait for warehouse processing (no compute charges)
6060
ctx.wait(null, Duration.ofHours(2));
6161

6262
// Step 3: Confirm shipment
6363
var shipment = ctx.step("confirm-shipment", Shipment.class,
64-
() -> shippingService.ship(reservation, order.getAddress()));
64+
stepCtx -> shippingService.ship(reservation, order.getAddress()));
6565

6666
return new OrderResult(order.getId(), shipment.getTrackingNumber());
6767
}

docs/adr/001-threaded-handler-execution.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ Durable functions need to suspend execution immediately at suspension points (wa
99

1010
```java
1111
public String handleRequest(MyInput input, DurableContext context) {
12-
var result1 = context.step("step1", () -> "first");
12+
var result1 = context.step("step1", stepCtx -> "first");
1313
context.wait(null, Duration.ofHours(1)); // Should suspend HERE
14-
var result2 = context.step("step2", () -> "second"); // Don't wait for this
14+
var result2 = context.step("step2", stepCtx -> "second"); // Don't wait for this
1515
return result1 + result2;
1616
}
1717
```
@@ -21,7 +21,7 @@ public String handleRequest(MyInput input, DurableContext context) {
2121
Run the handler in a background thread and race two futures:
2222

2323
```java
24-
var handlerFuture = CompletableFuture.supplyAsync(() -> handler.apply(input, context), executor);
24+
var handlerFuture = CompletableFuture.supplyAsync(stepCtx -> handler.apply(input, context), executor);
2525
var suspendFuture = executionManager.getSuspendExecutionFuture();
2626

2727
CompletableFuture.anyOf(handlerFuture, suspendFuture).join();

docs/adr/002-phaser-based-coordination.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ context.wait(null, Duration.ofMinutes(5)); // Root deregisters → immediate sus
1515

1616
### Complex Case: Blocking on Retrying Operations
1717
```java
18-
var future1 = context.stepAsync("step1", () -> failsAndRetries());
19-
var result = context.step("step2", () -> future1.get() + "-processed");
18+
var future1 = context.stepAsync("step1", stepCtx -> failsAndRetries());
19+
var result = context.step("step2", stepCtx -> future1.get() + "-processed");
2020
```
2121

2222
**Problem:** Simple thread counting fails because step2's thread would stay registered while blocked on `future1.get()`, preventing suspension during step1's retry delay.

docs/adr/004-child-context-execution.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ The TypeScript and Python durable execution SDKs support child contexts via `Ope
99

1010
```java
1111
var futureA = ctx.runInChildContextAsync("branch-a", String.class, child -> {
12-
child.step("validate", Void.class, () -> validate(order));
12+
child.step("validate", Void.class, stepCtx -> validate(order));
1313
child.wait(null, Duration.ofMinutes(5));
14-
return child.step("charge", String.class, () -> charge(order));
14+
return child.step("charge", String.class, stepCtx -> charge(order));
1515
});
1616
var futureB = ctx.runInChildContextAsync("branch-b", String.class, child -> { ... });
1717
var results = DurableFuture.allOf(futureA, futureB);

docs/advanced/error-handling.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ DurableExecutionException - General durable exception
2323
```java
2424
try {
2525
var result = ctx.step("charge-payment", Payment.class,
26-
() -> paymentService.charge(amount),
26+
stepCtx -> paymentService.charge(amount),
2727
StepConfig.builder()
2828
.semantics(StepSemantics.AT_MOST_ONCE_PER_RETRY)
2929
.build());

docs/advanced/testing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ You can also pass a lambda directly instead of a handler instance:
3232

3333
```java
3434
var runner = LocalDurableTestRunner.create(Order.class, (order, ctx) -> {
35-
var result = ctx.step("process", String.class, () -> "done");
35+
var result = ctx.step("process", String.class, stepCtx -> "done");
3636
return new OrderResult(order.getId(), result);
3737
});
3838
```

docs/core/child-contexts.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@ Child contexts run an isolated stream of work with their own operation counter a
55
```java
66
// Sync: blocks until the child context completes
77
var result = ctx.runInChildContext("validate-order", String.class, child -> {
8-
var data = child.step("fetch", String.class, () -> fetchData());
8+
var data = child.step("fetch", String.class, stepCtx -> fetchData());
99
child.wait(null, Duration.ofMinutes(5));
10-
return child.step("validate", String.class, () -> validate(data));
10+
return child.step("validate", String.class, stepCtx -> validate(data));
1111
});
1212

1313
// Async: returns a DurableFuture for concurrent execution
1414
var futureA = ctx.runInChildContextAsync("branch-a", String.class, child -> {
15-
return child.step("work-a", String.class, () -> doWorkA());
15+
return child.step("work-a", String.class, stepCtx -> doWorkA());
1616
});
1717
var futureB = ctx.runInChildContextAsync("branch-b", String.class, child -> {
18-
return child.step("work-b", String.class, () -> doWorkB());
18+
return child.step("work-b", String.class, stepCtx -> doWorkB());
1919
});
2020

2121
// Wait for all child contexts to complete

docs/core/steps.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ Steps execute your code and checkpoint the result. On replay, results from compl
44

55
```java
66
// Basic step (blocks until complete)
7-
var result = ctx.step("fetch-user", User.class, () -> userService.getUser(userId));
7+
var result = ctx.step("fetch-user", User.class, stepCtx -> userService.getUser(userId));
88

99
// Step with custom configuration (retries, semantics, serialization)
1010
var result = ctx.step("call-api", Response.class,
11-
() -> externalApi.call(request),
11+
stepCtx -> externalApi.call(request),
1212
StepConfig.builder()
1313
.retryStrategy(...)
1414
.semantics(...)
@@ -24,9 +24,9 @@ See [Step Configuration](#step-configuration) for retry strategies, delivery sem
2424
```java
2525
// Start multiple operations concurrently
2626
DurableFuture<User> userFuture = ctx.stepAsync("fetch-user", User.class,
27-
() -> userService.getUser(userId));
27+
stepCtx -> userService.getUser(userId));
2828
DurableFuture<List<Order>> ordersFuture = ctx.stepAsync("fetch-orders",
29-
new TypeToken<List<Order>>() {}, () -> orderService.getOrders(userId));
29+
new TypeToken<List<Order>>() {}, stepCtx -> orderService.getOrders(userId));
3030

3131
// Both operations run concurrently
3232
// Block and get results when needed
@@ -39,7 +39,7 @@ List<Order> orders = ordersFuture.get();
3939
Configure step behavior with `StepConfig`:
4040

4141
```java
42-
ctx.step("my-step", Result.class, () -> doWork(),
42+
ctx.step("my-step", Result.class, stepCtx -> doWork(),
4343
StepConfig.builder()
4444
.retryStrategy(...) // How to handle failures
4545
.semantics(...) // At-least-once vs at-most-once
@@ -78,11 +78,11 @@ Control how steps behave when interrupted mid-execution:
7878
```java
7979
// Default: at-least-once per retry (step may re-run if interrupted)
8080
var result = ctx.step("idempotent-update", Result.class,
81-
() -> database.upsert(record));
81+
stepCtx -> database.upsert(record));
8282

8383
// At-most-once per retry
8484
var result = ctx.step("send-email", Result.class,
85-
() -> emailService.send(notification),
85+
stepCtx -> emailService.send(notification),
8686
StepConfig.builder()
8787
.semantics(StepSemantics.AT_MOST_ONCE_PER_RETRY)
8888
.build());
@@ -98,7 +98,7 @@ To achieve step-level at-most-once semantics, combine with a no-retry strategy:
9898
```java
9999
// True at-most-once: step executes at most once, ever
100100
var result = ctx.step("charge-payment", Result.class,
101-
() -> paymentService.charge(amount),
101+
stepCtx -> paymentService.charge(amount),
102102
StepConfig.builder()
103103
.semantics(StepSemantics.AT_MOST_ONCE_PER_RETRY)
104104
.retryStrategy(RetryStrategies.Presets.NO_RETRY)
@@ -113,10 +113,10 @@ When a step returns a parameterized type like `List<User>`, use `TypeToken` to p
113113

114114
```java
115115
var users = ctx.step("fetch-users", new TypeToken<List<User>>() {},
116-
() -> userService.getAllUsers());
116+
stepCtx -> userService.getAllUsers());
117117

118118
var orderMap = ctx.step("fetch-orders", new TypeToken<Map<String, Order>>() {},
119-
() -> orderService.getOrdersByCustomer());
119+
stepCtx -> orderService.getOrdersByCustomer());
120120
```
121121

122122
This is needed for the SDK to deserialize a checkpointed result and get the exact type to reconstruct. See [TypeToken and Type Erasure](docs/internal-design.md#typetoken-and-type-erasure) for technical details.

docs/core/wait.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ ctx.wait("cooling-off-period", Duration.ofDays(7));
1919
DurableFuture<Void> timer = ctx.waitAsync("min-delay", Duration.ofSeconds(5));
2020

2121
// Do work while the timer runs
22-
var result = ctx.step("process", String.class, () -> doWork());
22+
var result = ctx.step("process", String.class, stepCtx -> doWork());
2323

2424
// Block until the wait elapses
2525
timer.get();

0 commit comments

Comments
 (0)