Skip to content

Commit f54d8a4

Browse files
committed
chore: remove anonymous form function override
1 parent 7c1e17d commit f54d8a4

7 files changed

Lines changed: 214 additions & 684 deletions

File tree

examples/src/main/java/software/amazon/lambda/durable/examples/callback/RetryWaitForCallbackExample.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* each time.
1818
*
1919
* <p>Each attempt uses a unique callback name ({@code "approval-1"}, {@code "approval-2"}, etc.) so the execution
20-
* history stays clean and replay-safe. The anonymous form is used, so attempts are grouped under a default-named child
20+
* history stays clean and replay-safe. A {@code null} name is used, so attempts are grouped under a default-named child
2121
* context.
2222
*/
2323
public class RetryWaitForCallbackExample extends DurableHandler<ApprovalRequest, String> {
@@ -34,6 +34,7 @@ public String handleRequest(ApprovalRequest input, DurableContext context) {
3434

3535
// Step 2: waitForCallback with retry — if the external system fails, try again with a fresh callback
3636
var approvalResult = context.withRetry(
37+
null,
3738
(ctx, attempt) -> ctx.waitForCallback(
3839
"approval-" + attempt, String.class, (callbackId, stepCtx) -> stepCtx.getLogger()
3940
.info("Attempt {}: sending callback {} to approval system", attempt, callbackId)),

examples/src/main/java/software/amazon/lambda/durable/examples/invoke/RetryInvokeExample.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* uses a unique operation name ({@code "call-greeting-1"}, {@code "call-greeting-2"}, etc.) so the execution history
1717
* stays clean and replay-safe.
1818
*
19-
* <p>The anonymous form is used, so attempts are grouped under a default-named child context.
19+
* <p>A {@code null} name is used, so attempts are grouped under a default-named child context.
2020
*/
2121
public class RetryInvokeExample extends DurableHandler<GreetingRequest, String> {
2222

@@ -25,6 +25,7 @@ public class RetryInvokeExample extends DurableHandler<GreetingRequest, String>
2525
@Override
2626
public String handleRequest(GreetingRequest input, DurableContext context) {
2727
return context.withRetry(
28+
null,
2829
(ctx, attempt) -> ctx.invoke(
2930
"call-greeting-" + attempt,
3031
"simple-step-example" + input.getName() + ":$LATEST",

sdk-integration-tests/src/test/java/software/amazon/lambda/durable/RetryInvokeIntegrationTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ void invokeSucceedsOnFirstAttempt() {
2121
var runner = LocalDurableTestRunner.create(
2222
String.class,
2323
(input, context) -> context.withRetry(
24+
null,
2425
(ctx, attempt) -> ctx.invoke("invoke-" + attempt, "target-fn", "{}", String.class),
2526
WithRetryConfig.builder()
2627
.retryStrategy(RetryStrategies.fixedDelay(3, Duration.ofSeconds(2)))
@@ -41,6 +42,7 @@ void invokeRetriesAfterFailure() {
4142
var runner = LocalDurableTestRunner.create(
4243
String.class,
4344
(input, context) -> context.withRetry(
45+
null,
4446
(ctx, attempt) -> ctx.invoke("invoke-" + attempt, "target-fn", "{}", String.class),
4547
WithRetryConfig.builder()
4648
.retryStrategy(RetryStrategies.fixedDelay(3, Duration.ofSeconds(2)))
@@ -78,6 +80,7 @@ void invokeFailsAfterAllRetriesExhausted() {
7880
var runner = LocalDurableTestRunner.create(
7981
String.class,
8082
(input, context) -> context.withRetry(
83+
null,
8184
(ctx, attempt) -> ctx.invoke("invoke-" + attempt, "target-fn", "{}", String.class),
8285
WithRetryConfig.builder()
8386
.retryStrategy((error, attempt) ->
@@ -111,6 +114,7 @@ void invokeRetryWithCustomBackoffDelay() {
111114
var runner = LocalDurableTestRunner.create(
112115
String.class,
113116
(input, context) -> context.withRetry(
117+
null,
114118
(ctx, attempt) -> ctx.invoke("invoke-" + attempt, "target-fn", "{}", String.class),
115119
WithRetryConfig.builder()
116120
.retryStrategy((error, attempt) -> attempt < 3
@@ -144,6 +148,7 @@ void invokeRetryWithStepsBeforeAndAfter() {
144148
var prefix = context.step("prepare", String.class, stepCtx -> "prepared");
145149

146150
var invokeResult = context.withRetry(
151+
null,
147152
(ctx, attempt) -> ctx.invoke("invoke-" + attempt, "target-fn", "{}", String.class),
148153
WithRetryConfig.builder()
149154
.retryStrategy(RetryStrategies.fixedDelay(3, Duration.ofSeconds(1)))
@@ -169,6 +174,7 @@ void invokeRetryPreservesOriginalExceptionType() {
169174
var runner = LocalDurableTestRunner.create(String.class, (input, context) -> {
170175
try {
171176
return context.withRetry(
177+
null,
172178
(ctx, attempt) -> ctx.invoke("invoke-" + attempt, "target-fn", "{}", String.class),
173179
WithRetryConfig.builder()
174180
.retryStrategy(RetryStrategies.Presets.NO_RETRY)

sdk-integration-tests/src/test/java/software/amazon/lambda/durable/RetryWaitForCallbackIntegrationTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ void waitForCallbackSucceedsOnFirstAttempt() {
2020
var runner = LocalDurableTestRunner.create(
2121
String.class,
2222
(input, context) -> context.withRetry(
23+
null,
2324
(ctx, attempt) -> ctx.waitForCallback(
2425
"approval-" + attempt, String.class, (callbackId, stepCtx) -> stepCtx.getLogger()
2526
.info("Submitting callback {}", callbackId)),
@@ -46,6 +47,7 @@ void waitForCallbackRetriesAfterFailure() {
4647
var runner = LocalDurableTestRunner.create(
4748
String.class,
4849
(input, context) -> context.withRetry(
50+
null,
4951
(ctx, attempt) -> ctx.waitForCallback(
5052
"approval-" + attempt, String.class, (callbackId, stepCtx) -> stepCtx.getLogger()
5153
.info("Attempt {} callback {}", attempt, callbackId)),
@@ -92,6 +94,7 @@ void waitForCallbackFailsAfterAllRetriesExhausted() {
9294
var runner = LocalDurableTestRunner.create(
9395
String.class,
9496
(input, context) -> context.withRetry(
97+
null,
9598
(ctx, attempt) ->
9699
ctx.waitForCallback("approval-" + attempt, String.class, (callbackId, stepCtx) -> {}),
97100
WithRetryConfig.builder()
@@ -129,6 +132,7 @@ void waitForCallbackRetryWithStepsBeforeAndAfter() {
129132
var prefix = context.step("prepare", String.class, stepCtx -> "prepared");
130133

131134
var callbackResult = context.withRetry(
135+
null,
132136
(ctx, attempt) ->
133137
ctx.waitForCallback("approval-" + attempt, String.class, (callbackId, stepCtx) -> {}),
134138
WithRetryConfig.builder()
@@ -157,6 +161,7 @@ void waitForCallbackRetryMultipleFailuresThenSuccess() {
157161
var runner = LocalDurableTestRunner.create(
158162
String.class,
159163
(input, context) -> context.withRetry(
164+
null,
160165
(ctx, attempt) ->
161166
ctx.waitForCallback("cb-" + attempt, String.class, (callbackId, stepCtx) -> {}),
162167
WithRetryConfig.builder()
@@ -202,6 +207,7 @@ void waitForCallbackRetryWithSubmitterLogic() {
202207
var runner = LocalDurableTestRunner.create(
203208
String.class,
204209
(input, context) -> context.withRetry(
210+
null,
205211
(ctx, attempt) ->
206212
ctx.waitForCallback("approval-" + attempt, String.class, (callbackId, stepCtx) -> {
207213
// Submitter runs each attempt — in a real scenario this would

sdk/src/main/java/software/amazon/lambda/durable/DurableContext.java

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ <T> DurableFuture<T> waitForConditionAsync(
732732
// =============== withRetry ================
733733

734734
/**
735-
* Replay-safe retry loop for any durable operation (named form, sync).
735+
* Replay-safe retry loop for any durable operation (sync).
736736
*
737737
* <p>Provides the same retry-with-backoff pattern that {@code step()} has built in, but for operations that cannot
738738
* live inside a step ({@code waitForCallback}, {@code invoke}, {@code waitForCondition}, etc.).
@@ -746,7 +746,8 @@ <T> DurableFuture<T> waitForConditionAsync(
746746
* used — no checkpointing overhead, but the child re-executes on replay.
747747
*
748748
* @param <T> the result type
749-
* @param name operation name (used for backoff wait names, and as the child context name when wrapping)
749+
* @param name operation name (used for backoff wait names, and as the child context name when wrapping); pass
750+
* {@code null} for an anonymous retry whose backoff waits use default names
750751
* @param operation the retryable operation — receives the context and 1-based attempt number
751752
* @param config retry configuration including the retry strategy and child context wrapping
752753
* @return the operation result
@@ -756,53 +757,22 @@ default <T> T withRetry(String name, WithRetry<T> operation, WithRetryConfig con
756757
}
757758

758759
/**
759-
* Replay-safe retry loop for any durable operation (anonymous form, sync).
760+
* Replay-safe retry loop for any durable operation (async).
760761
*
761762
* <p>The retry loop always runs in a child context to provide an isolated operation ID namespace. If
762763
* {@link WithRetryConfig#wrapInChildContext()} is enabled, the child context is checkpointed (persisted) so all
763764
* attempts are grouped under a single named operation in execution history. Otherwise, a virtual child context is
764765
* used — no checkpointing overhead, but the child re-executes on replay.
765766
*
766767
* @param <T> the result type
767-
* @param operation the retryable operation — receives the context and 1-based attempt number
768-
* @param config retry configuration including the retry strategy and child context wrapping
769-
* @return the operation result
770-
*/
771-
default <T> T withRetry(WithRetry<T> operation, WithRetryConfig config) {
772-
return withRetryAsync(operation, config).get();
773-
}
774-
775-
/**
776-
* Replay-safe retry loop for any durable operation (named form, async).
777-
*
778-
* <p>The retry loop always runs in a child context to provide an isolated operation ID namespace. If
779-
* {@link WithRetryConfig#wrapInChildContext()} is enabled, the child context is checkpointed (persisted) so all
780-
* attempts are grouped under a single named operation in execution history. Otherwise, a virtual child context is
781-
* used — no checkpointing overhead, but the child re-executes on replay.
782-
*
783-
* @param <T> the result type
784-
* @param name operation name (used for child context and backoff wait names)
768+
* @param name operation name (used for child context and backoff wait names); pass {@code null} for an anonymous
769+
* retry whose backoff waits use default names
785770
* @param operation the retryable operation — receives the context and 1-based attempt number
786771
* @param config retry configuration including the retry strategy
787772
* @return a future representing the operation result
788773
*/
789774
<T> DurableFuture<T> withRetryAsync(String name, WithRetry<T> operation, WithRetryConfig config);
790775

791-
/**
792-
* Replay-safe retry loop for any durable operation (anonymous form, async).
793-
*
794-
* <p>The retry loop always runs in a child context to provide an isolated operation ID namespace. If
795-
* {@link WithRetryConfig#wrapInChildContext()} is enabled, the child context is checkpointed (persisted) so all
796-
* attempts are grouped under a single named operation in execution history. Otherwise, a virtual child context is
797-
* used — no checkpointing overhead, but the child re-executes on replay.
798-
*
799-
* @param <T> the result type
800-
* @param operation the retryable operation — receives the context and 1-based attempt number
801-
* @param config retry configuration including the retry strategy
802-
* @return a future representing the operation result
803-
*/
804-
<T> DurableFuture<T> withRetryAsync(WithRetry<T> operation, WithRetryConfig config);
805-
806776
/**
807777
* Function applied to each item in a map operation.
808778
*

sdk/src/main/java/software/amazon/lambda/durable/context/DurableContextImpl.java

Lines changed: 8 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -238,25 +238,6 @@ private <T> DurableFuture<T> runInChildContextAsync(
238238
Function<DurableContext, T> func,
239239
RunInChildContextConfig config,
240240
OperationSubType subType) {
241-
return runInChildContextAsync(name, resultType, func, config, subType, false);
242-
}
243-
244-
private <T> DurableFuture<T> runInVirtualChildContextAsync(
245-
String name,
246-
TypeToken<T> resultType,
247-
Function<DurableContext, T> func,
248-
RunInChildContextConfig config,
249-
OperationSubType subType) {
250-
return runInChildContextAsync(name, resultType, func, config, subType, true);
251-
}
252-
253-
private <T> DurableFuture<T> runInChildContextAsync(
254-
String name,
255-
TypeToken<T> resultType,
256-
Function<DurableContext, T> func,
257-
RunInChildContextConfig config,
258-
OperationSubType subType,
259-
boolean isVirtual) {
260241
Objects.requireNonNull(resultType, "resultType cannot be null");
261242
Objects.requireNonNull(config, "RunInChildContextConfig cannot be null");
262243
ParameterValidator.validateOperationName(name);
@@ -272,9 +253,7 @@ private <T> DurableFuture<T> runInChildContextAsync(
272253
func,
273254
resultType,
274255
config,
275-
this,
276-
isVirtual,
277-
null);
256+
this);
278257

279258
operation.execute();
280259
return operation;
@@ -402,45 +381,18 @@ public <T> DurableFuture<T> waitForConditionAsync(
402381
@Override
403382
@SuppressWarnings("unchecked")
404383
public <T> DurableFuture<T> withRetryAsync(String name, WithRetry<T> operation, WithRetryConfig config) {
405-
Objects.requireNonNull(name, "name cannot be null");
406384
Objects.requireNonNull(operation, "operation cannot be null");
407385
Objects.requireNonNull(config, "config cannot be null");
408386

409-
if (config.wrapInChildContext()) {
410-
return (DurableFuture<T>) runInChildContextAsync(
411-
name,
412-
new TypeToken<Object>() {},
413-
childCtx -> executeRetryLoop(childCtx, name, operation, config),
414-
RunInChildContextConfig.builder().build(),
415-
OperationSubType.WITH_RETRY);
416-
}
417-
return (DurableFuture<T>) runInVirtualChildContextAsync(
418-
name,
419-
new TypeToken<Object>() {},
420-
childCtx -> executeRetryLoop(childCtx, name, operation, config),
421-
RunInChildContextConfig.builder().build(),
422-
OperationSubType.WITH_RETRY);
423-
}
424-
425-
@Override
426-
@SuppressWarnings("unchecked")
427-
public <T> DurableFuture<T> withRetryAsync(WithRetry<T> operation, WithRetryConfig config) {
428-
Objects.requireNonNull(operation, "operation cannot be null");
429-
Objects.requireNonNull(config, "config cannot be null");
387+
var childContextName = name != null ? name : ANONYMOUS_CHILD_CONTEXT_NAME;
430388

431-
if (config.wrapInChildContext()) {
432-
return (DurableFuture<T>) runInChildContextAsync(
433-
ANONYMOUS_CHILD_CONTEXT_NAME,
434-
new TypeToken<Object>() {},
435-
childCtx -> executeRetryLoop(childCtx, null, operation, config),
436-
RunInChildContextConfig.builder().build(),
437-
OperationSubType.WITH_RETRY);
438-
}
439-
return (DurableFuture<T>) runInVirtualChildContextAsync(
440-
ANONYMOUS_CHILD_CONTEXT_NAME,
389+
return (DurableFuture<T>) runInChildContextAsync(
390+
childContextName,
441391
new TypeToken<Object>() {},
442-
childCtx -> executeRetryLoop(childCtx, null, operation, config),
443-
RunInChildContextConfig.builder().build(),
392+
childCtx -> executeRetryLoop(childCtx, name, operation, config),
393+
RunInChildContextConfig.builder()
394+
.isVirtual(!config.wrapInChildContext())
395+
.build(),
444396
OperationSubType.WITH_RETRY);
445397
}
446398

0 commit comments

Comments
 (0)