Add WaitForConditionAsync polling primitive (DOTNET-8665)#2376
Draft
GarrettBeatty wants to merge 1 commit into
Draft
Add WaitForConditionAsync polling primitive (DOTNET-8665)#2376GarrettBeatty wants to merge 1 commit into
GarrettBeatty wants to merge 1 commit into
Conversation
|
|
||
| COPY bin/publish/ ${LAMBDA_TASK_ROOT} | ||
|
|
||
| ENTRYPOINT ["/var/task/bootstrap"] |
|
|
||
| COPY bin/publish/ ${LAMBDA_TASK_ROOT} | ||
|
|
||
| ENTRYPOINT ["/var/task/bootstrap"] |
|
|
||
| COPY bin/publish/ ${LAMBDA_TASK_ROOT} | ||
|
|
||
| ENTRYPOINT ["/var/task/bootstrap"] |
|
|
||
| COPY bin/publish/ ${LAMBDA_TASK_ROOT} | ||
|
|
||
| ENTRYPOINT ["/var/task/bootstrap"] |
|
|
||
| COPY bin/publish/ ${LAMBDA_TASK_ROOT} | ||
|
|
||
| ENTRYPOINT ["/var/task/bootstrap"] |
464c591 to
d308c3b
Compare
87688ca to
7f91202
Compare
Adds service-mediated polling to the .NET Durable Execution SDK. WaitForConditionAsync repeatedly evaluates a check function with configurable wait strategy between attempts; each iteration is its own Lambda invocation (suspended via STEP+RETRY checkpoints carrying NextAttemptDelaySeconds), so polling does not consume compute time. Public surface: - IDurableContext.WaitForConditionAsync<TState> (reflection + AOT-safe overloads taking ICheckpointSerializer<TState>) - IConditionCheckContext (Logger + AttemptNumber) - WaitForConditionConfig<TState> (required InitialState + WaitStrategy) - IWaitStrategy<TState> with Decide(state, attempt) returning WaitDecision - WaitDecision (readonly record struct, ShouldContinue + Delay, Stop() / ContinueAfter(TimeSpan) factories) - WaitStrategy factories: Exponential / Linear / Fixed / FromDelegate, each accepting an optional Func<TState, bool> isDone predicate - WaitForConditionException with AttemptsExhausted and LastState (preserved across both live execution and replay) Internal: - WaitForConditionOperation<TState> wire format = STEP + SubType "WaitForCondition". Each polling iteration emits Action=RETRY with the new state in payload and NextAttemptDelaySeconds for the service to schedule the next invocation. - Strategies signal max-attempts exhausted by throwing WaitForConditionException directly from Decide(); the operation enriches with LastState before checkpointing FAIL. - LastState survives FAIL replay: serialized into FAIL payload at write time, deserialized in BuildFailureException with warning-logged fallback for legacy/corrupt data. - ExponentialBackoff helper extracted for sharing with ExponentialRetryStrategy. Math is byte-for-byte identical. - Reuses OperationSubTypes.WaitForCondition from Wave 0. Defaults: 60 attempts / 5s initial / 300s max / 1.5x rate / Full jitter - distinct from RetryStrategy.Default and matching Python/JS/Java reference SDKs. (Note: Python returns success on max-attempts; .NET/Java/JS throw - documented in design doc.) Adds 41 unit tests + 5 integration tests covering each wait strategy, isDone predicate paths, max-attempts exhaustion, user-check exceptions, replay determinism, exponential backoff bounds, and corrupt-payload fallback logging. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7f91202 to
3fa06ce
Compare
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.
Summary
Adds service-mediated polling to the .NET Durable Execution SDK.
WaitForConditionAsyncrepeatedly evaluates a check function with configurable wait strategy between attempts; each iteration is its own Lambda invocation (suspended via STEP+RETRY checkpoints carryingNextAttemptDelaySeconds), so polling does not consume compute time.Stacked on top of #2372 (Wave 0 cross-cutting types).
Fixes DOTNET-8665.
Public surface
IDurableContext.WaitForConditionAsync<TState>(reflection + AOT-safe overloads takingICheckpointSerializer<TState>)IConditionCheckContext(Logger + AttemptNumber)WaitForConditionConfig<TState>(required InitialState + WaitStrategy)IWaitStrategy<TState>withDecide(state, attempt)returningWaitDecisionWaitDecision(readonly record struct;ShouldContinue+Delay;Stop()/ContinueAfter(TimeSpan)factories)WaitStrategyfactories:Exponential/Linear/Fixed/FromDelegate, each accepting an optionalFunc<TState, bool>isDonepredicateWaitForConditionExceptionwithAttemptsExhaustedandLastState(preserved across both live execution and replay)Internal
WaitForConditionOperation<TState>wire format = STEP + SubType"WaitForCondition". Each polling iteration emitsAction=RETRYwith the new state in payload andNextAttemptDelaySecondsfor the service to schedule the next invocation.WaitForConditionExceptiondirectly fromDecide(); the operation enriches withLastStatebefore checkpointing FAIL.LastStatesurvives FAIL replay: serialized into FAIL payload at write time, deserialized inBuildFailureExceptionwith warning-logged fallback for legacy/corrupt data.ExponentialBackoffhelper extracted for sharing withExponentialRetryStrategy. Math is byte-for-byte identical.OperationSubTypes.WaitForConditionfrom Wave 0.Defaults
60 attempts / 5s initial / 300s max / 1.5x rate / Full jitter — distinct from
RetryStrategy.Defaultand matching Python/JS/Java reference SDKs.Test plan
🤖 Generated with Claude Code