Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
Issue Link, if available
N/A
Description
Add a public
retryOperationhelper that retries any durable operation (waitForCallback,invoke,waitForCondition, etc.) end-to-end with configurable backoff. Today users have to hand-roll a while loop with manualcontext.wait()backoff calls. This helper provides a single, replay-safe, well-tested primitive for that pattern, reusing the exact sameRetryStrategyshape developers already know fromStepConfig.New files:
RetryableOperation<T>(sdk/.../util/) —@FunctionalInterfacethat takes(DurableContext, int attempt)and returnsT. Enables lambda syntax for the operation to retry.RetryOperationConfig(sdk/.../config/) — Builder-pattern config holding theRetryStrategy(required, same type asStepConfig) andwrapInChildContext(defaults totrue).RetryOperationHelper(sdk/.../util/) — Static utility with two overloads:retryOperation(context, name, operation, config)— wraps inrunInChildContextby default for clean execution history grouping.retryOperation(context, operation, config)— runs directly in the caller's context, no wrapping.Key behaviors:
RetryStrategy/RetryDecisiontypes — zero new retry concepts.operation.execute()calls durable primitives,context.wait()handles backoff).SuspendExecutionExceptionandUnrecoverableDurableExecutionExceptionwithout retrying — these are internal SDK control flow signals.RetryDecision.delay()isDuration.ZERO.Demo/Screenshots
N/A — utility library change, no UI.
Checklist
Testing
Unit Tests
Yes. 36 unit tests across 3 test classes in
sdk/src/test/:RetryOperationConfigTest(8 tests) — builder validation, defaults, required fields, chaining.RetryOperationHelperTest(24 tests in 3 nested classes):NamedForm(9) — child-context wrapping, opt-out, backoff wait naming, default delay, null validation.AnonymousForm(7) — no wrapping, anonymous backoff naming, exception identity, null validation.RetryBehavior(8) — attempt numbers, error forwarding, custom delays, context passthrough,SuspendExecutionExceptionpropagation,UnrecoverableDurableExecutionExceptionpropagation, retry exhaustion.RetryableOperationTest(4 tests) — lambda implementation, context/attempt passthrough, exception propagation, null return.Integration Tests
Yes. 12 integration tests across 2 test classes in
sdk-integration-tests/src/test/:RetryInvokeIntegrationTest(6 tests) — first-attempt success, retry after failure, all retries exhausted, custom backoff delays, composition with steps, original exception type preservation.RetryWaitForCallbackIntegrationTest(6 tests) — first-attempt success, retry after callback failure, all retries exhausted, composition with steps, multiple failures then success, submitter re-execution on each retry.Examples
Yes. 2 example handlers with 8 example tests in
examples/:RetryInvokeExample+RetryInvokeExampleTest(4 tests) — demonstratesretryOperationwrappingcontext.invokewith retry on transient failures.RetryWaitForCallbackExample+RetryWaitForCallbackExampleTest(4 tests) — demonstratesretryOperationwrappingcontext.waitForCallbackwith retry on callback rejection.