-
Notifications
You must be signed in to change notification settings - Fork 501
Add ParallelAsync for concurrent branch execution (DOTNET-8662) #2375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feature/durablefunction
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "Projects": [ | ||
| { | ||
| "Name": "Amazon.Lambda.DurableExecution", | ||
| "Type": "Patch", | ||
| "ChangelogMessages": [ | ||
| "Add `ParallelAsync` to `IDurableContext` for running multiple workflow branches concurrently with automatic checkpointing. Supports configurable max concurrency, failure tolerance, and first-successful completion via `ParallelConfig`, returning an `IBatchResult<T>`." | ||
| ] | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| namespace Amazon.Lambda.DurableExecution; | ||
|
|
||
| /// <summary> | ||
| /// Status of an individual item in a <see cref="IBatchResult{T}"/>. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// Mirrors the wire-state of the per-branch checkpoint at the moment the batch | ||
| /// resolved. Items that finished produce <see cref="Succeeded"/> or | ||
| /// <see cref="Failed"/>; items that were not dispatched because a | ||
| /// <see cref="CompletionConfig"/> short-circuit fired are reported as | ||
| /// <see cref="Started"/>. | ||
| /// </remarks> | ||
|
GarrettBeatty marked this conversation as resolved.
|
||
| public enum BatchItemStatus | ||
| { | ||
| /// <summary> | ||
| /// The branch ran to completion and produced a result. | ||
| /// </summary> | ||
| Succeeded, | ||
|
|
||
| /// <summary> | ||
| /// The branch ran to completion and threw. | ||
| /// </summary> | ||
| Failed, | ||
|
|
||
| /// <summary> | ||
| /// The branch was not dispatched before the batch's <see cref="CompletionConfig"/> | ||
| /// resolved (e.g., <see cref="CompletionConfig.FirstSuccessful"/> short-circuited | ||
| /// before this branch was started), or no per-branch checkpoint exists on replay. | ||
| /// </summary> | ||
| Started | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| namespace Amazon.Lambda.DurableExecution; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add license header |
||
|
|
||
| /// <summary> | ||
| /// Defines completion criteria for parallel/map operations. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// Construct via the static factories (<see cref="AllSuccessful"/>, | ||
| /// <see cref="AllCompleted"/>, <see cref="FirstSuccessful"/>) or set the | ||
| /// individual properties directly. Multiple criteria combine: the operation | ||
| /// resolves as soon as any criterion is met (success short-circuit) or violated | ||
| /// (failure short-circuit). | ||
| /// </remarks> | ||
| public sealed class CompletionConfig | ||
| { | ||
| private int? _minSuccessful; | ||
| private int? _toleratedFailureCount; | ||
| private double? _toleratedFailurePercentage; | ||
|
|
||
| /// <summary> | ||
| /// Minimum number of <see cref="BatchItemStatus.Succeeded"/> items required | ||
| /// before the operation resolves successfully. <c>null</c> = no minimum. | ||
| /// </summary> | ||
| /// <exception cref="System.ArgumentOutOfRangeException"> | ||
| /// Thrown by the setter if the value is less than <c>1</c>. A minimum of | ||
| /// zero (or negative) would resolve the operation immediately without | ||
| /// dispatching any branch. | ||
| /// </exception> | ||
| public int? MinSuccessful | ||
| { | ||
| get => _minSuccessful; | ||
| set | ||
| { | ||
| if (value is { } v && v < 1) | ||
| { | ||
| throw new ArgumentOutOfRangeException(nameof(value), v, | ||
| "MinSuccessful must be at least 1."); | ||
| } | ||
| _minSuccessful = value; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Maximum tolerated <see cref="BatchItemStatus.Failed"/> count. When the | ||
| /// failure count <i>strictly exceeds</i> this value, the operation resolves | ||
| /// with <see cref="CompletionReason.FailureToleranceExceeded"/>. | ||
| /// <c>null</c> = no count-based failure threshold. | ||
| /// </summary> | ||
| /// <exception cref="System.ArgumentOutOfRangeException"> | ||
| /// Thrown by the setter if the value is negative. A negative tolerance | ||
| /// would fail the operation immediately without dispatching any branch. | ||
| /// </exception> | ||
| public int? ToleratedFailureCount | ||
| { | ||
| get => _toleratedFailureCount; | ||
| set | ||
| { | ||
| if (value is { } v && v < 0) | ||
| { | ||
| throw new ArgumentOutOfRangeException(nameof(value), v, | ||
| "ToleratedFailureCount must be zero or greater."); | ||
| } | ||
| _toleratedFailureCount = value; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Maximum tolerated failure ratio, expressed as a value in the range | ||
| /// <c>0.0</c> to <c>1.0</c> (inclusive). For example, <c>0.25</c> means | ||
| /// "tolerate up to 25% failures; fail when the failure ratio strictly | ||
| /// exceeds 25%". <c>null</c> = no ratio-based failure threshold. | ||
| /// </summary> | ||
| /// <exception cref="System.ArgumentOutOfRangeException"> | ||
| /// Thrown by the setter if the value is outside <c>[0.0, 1.0]</c>. | ||
| /// </exception> | ||
| public double? ToleratedFailurePercentage | ||
| { | ||
| get => _toleratedFailurePercentage; | ||
| set | ||
| { | ||
| if (value is { } v && (v < 0.0 || v > 1.0)) | ||
| { | ||
| throw new ArgumentOutOfRangeException(nameof(value), v, | ||
| "ToleratedFailurePercentage must be a ratio in [0.0, 1.0]."); | ||
| } | ||
| _toleratedFailurePercentage = value; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// All items must succeed. Equivalent to | ||
| /// <see cref="ToleratedFailureCount"/> = 0. The default for | ||
| /// <see cref="ParallelConfig.CompletionConfig"/>. | ||
| /// </summary> | ||
| public static CompletionConfig AllSuccessful() => new() { ToleratedFailureCount = 0 }; | ||
|
|
||
| /// <summary> | ||
| /// Run every branch regardless of failures; surface failures per-item via | ||
| /// <see cref="IBatchResult{T}.Failed"/>. Resolution does not auto-throw — | ||
| /// the caller can inspect the result and call | ||
| /// <see cref="IBatchResult{T}.ThrowIfError"/> if they want strict-success | ||
| /// behavior. | ||
| /// </summary> | ||
| public static CompletionConfig AllCompleted() => new(); | ||
|
|
||
| /// <summary> | ||
| /// Resolve once at least one branch has succeeded. Branches that were not | ||
| /// dispatched before the completion criteria was met are reported as | ||
| /// <see cref="BatchItemStatus.Started"/>. | ||
| /// </summary> | ||
|
GarrettBeatty marked this conversation as resolved.
|
||
| public static CompletionConfig FirstSuccessful() => new() { MinSuccessful = 1 }; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| namespace Amazon.Lambda.DurableExecution; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add license header |
||
|
|
||
| /// <summary> | ||
| /// Why a batch operation (<see cref="IDurableContext.ParallelAsync{T}(IReadOnlyList{System.Func{IDurableContext, System.Threading.Tasks.Task{T}}}, string?, ParallelConfig?, System.Threading.CancellationToken)"/> | ||
| /// or future Map) resolved. | ||
| /// </summary> | ||
| public enum CompletionReason | ||
| { | ||
| /// <summary> | ||
| /// Every branch finished — no <see cref="CompletionConfig"/> short-circuit | ||
| /// was triggered. Branches may be a mix of <see cref="BatchItemStatus.Succeeded"/> | ||
| /// and <see cref="BatchItemStatus.Failed"/>. | ||
| /// </summary> | ||
| AllCompleted, | ||
|
|
||
| /// <summary> | ||
| /// <see cref="CompletionConfig.MinSuccessful"/> branches succeeded; remaining | ||
| /// branches were left in <see cref="BatchItemStatus.Started"/>. | ||
| /// </summary> | ||
| MinSuccessfulReached, | ||
|
|
||
| /// <summary> | ||
| /// <see cref="CompletionConfig.ToleratedFailureCount"/> or | ||
| /// <see cref="CompletionConfig.ToleratedFailurePercentage"/> was exceeded. | ||
| /// The batch is considered failed and surfaces a | ||
| /// <see cref="ParallelException"/> when awaited. | ||
| /// </summary> | ||
| FailureToleranceExceeded | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| namespace Amazon.Lambda.DurableExecution; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add license header |
||
|
|
||
| /// <summary> | ||
| /// A named branch for | ||
| /// <see cref="IDurableContext.ParallelAsync{T}(IReadOnlyList{DurableBranch{T}}, string?, ParallelConfig?, System.Threading.CancellationToken)"/>. | ||
| /// Names appear in execution traces and on the wire <c>OperationUpdate.Name</c> | ||
| /// field, and surface on <see cref="IBatchItem{T}.Name"/>. | ||
| /// </summary> | ||
| /// <typeparam name="T">The branch's result type.</typeparam> | ||
| /// <param name="Name">Human-readable branch name. Required.</param> | ||
| /// <param name="Func">The user function executed inside the branch's | ||
| /// child context.</param> | ||
| public sealed record DurableBranch<T>(string Name, Func<IDurableContext, Task<T>> Func); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add license header