.NET: [Feature Branch] Add basic durable workflow support#3648
.NET: [Feature Branch] Add basic durable workflow support#3648kshyju wants to merge 5 commits intomicrosoft:feat/durable_taskfrom
Conversation
| [Collection("Samples")] | ||
| [Trait("Category", "SampleValidation")] | ||
| public sealed class ConsoleAppSamplesValidation(ITestOutputHelper outputHelper) : IAsyncLifetime | ||
| public sealed class ConsoleAppSamplesValidation(ITestOutputHelper outputHelper) : SamplesValidationBase(outputHelper) |
There was a problem hiding this comment.
The change here is to move common logic to SamplesValidationBase so that both this and the workflow's console app samples validation IT can use same code.
| } | ||
| } | ||
|
|
||
| private sealed class DefaultDataConverter : DataConverter |
There was a problem hiding this comment.
This class was moved to DurableDataConverter (renamed)
| /// This converter handles special cases like <see cref="DurableAgentState"/> using source-generated | ||
| /// JSON contexts for AOT compatibility, and falls back to reflection-based serialization for other types. | ||
| /// </remarks> | ||
| internal sealed class DurableDataConverter : DataConverter |
There was a problem hiding this comment.
This was the previously called DefaultDataConverter. I moved it to this file and renamed.
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <InternalsVisibleTo Include="Microsoft.Agents.AI.DurableTask" /> |
There was a problem hiding this comment.
This was added after talking to MAF folks. we are still discussing the proposal about the api change which may go in the core library. In that case, this will be removed.
| /// Base class for sample validation integration tests providing shared infrastructure | ||
| /// setup and utility methods for running console app samples. | ||
| /// </summary> | ||
| public abstract class SamplesValidationBase : IAsyncLifetime |
There was a problem hiding this comment.
Code here is moved from the existing agents console app samples validation file.
There was a problem hiding this comment.
Pull request overview
This PR introduces the initial infrastructure for running Microsoft.Agents.AI.Workflows.Workflow graphs as Durable Task orchestrations, plus samples and tests that exercise sequential and concurrent patterns.
Changes:
- Add durable workflow runtime components (options, DI extensions, orchestration runner, edge routing, executor dispatch, and JSON context) under
Microsoft.Agents.AI.DurableTask. - Add public workflow execution APIs (
IWorkflowClient,IWorkflowRun,IAwaitableWorkflowRun) and wire them into the Durable Task registration pipeline. - Add two durable workflow console samples (sequential and fan-out/fan-in with AI agents) and corresponding integration tests that validate them end-to-end, including shared DTS/Redis test infrastructure.
Reviewed changes
Copilot reviewed 46 out of 46 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| dotnet/tests/Microsoft.Agents.AI.DurableTask.UnitTests/Workflows/WorkflowNamingHelperTests.cs | Adds unit tests for workflow/orchestration name conversion and executor ID parsing. |
| dotnet/tests/Microsoft.Agents.AI.DurableTask.UnitTests/Microsoft.Agents.AI.DurableTask.UnitTests.csproj | References the Workflows project so workflow-related tests can compile. |
| dotnet/tests/Microsoft.Agents.AI.DurableTask.IntegrationTests/WorkflowConsoleAppSamplesValidation.cs | Adds integration tests that drive the new durable workflow console samples and assert expected log lines and completion. |
| dotnet/tests/Microsoft.Agents.AI.DurableTask.IntegrationTests/SamplesValidationBase.cs | Introduces shared infra for console-sample integration tests (DTS/Redis bootstrapping, process I/O, log streaming). |
| dotnet/tests/Microsoft.Agents.AI.DurableTask.IntegrationTests/ConsoleAppSamplesValidation.cs | Refactors durable agent sample tests to reuse SamplesValidationBase and rely on overridden env-var wiring (e.g., Redis) for agents. |
| dotnet/src/Microsoft.Agents.AI.Workflows/Microsoft.Agents.AI.Workflows.csproj | Grants internals visibility to Microsoft.Agents.AI.DurableTask so workflows internals can be analyzed. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/WorkflowNamingHelper.cs | Centralizes naming conventions for orchestration function names and executor IDs, including stripping GUID suffixes. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/WorkflowGraphInfo.cs | Defines the minimal graph representation (successors, predecessors, conditions, output types) used for message-driven superstep execution. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/WorkflowAnalyzer.cs | Analyzes Workflow instances into WorkflowExecutorInfo and WorkflowGraphInfo, identifies agent executors, and extracts executor output types. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/SentMessageInfo.cs | Models messages emitted from executors via IWorkflowContext.SendMessageAsync for durable transport. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/IWorkflowRun.cs | Public interface describing a workflow run by ID and exposing outgoing/new WorkflowEvent streams. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/IWorkflowClient.cs | Public client interface for starting workflows with typed or string inputs and obtaining IWorkflowRun handles. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/IAwaitableWorkflowRun.cs | Public interface extending IWorkflowRun with WaitForCompletionAsync<TResult> for runs that support awaiting completion. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/ExecutorRegistry.cs | Internal registry mapping logical executor names to bindings for later instantiation, and a helper ExecutorRegistration record. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/EdgeRouters/IDurableEdgeRouter.cs | Defines the routing contract for delivering messages between executors in a durable workflow. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/EdgeRouters/DurableFanOutEdgeRouter.cs | Implements fan-out routing from a single source to multiple target edge routers. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/EdgeRouters/DurableEdgeMap.cs | Builds per-executor routing tables and predecessor counts from WorkflowGraphInfo and manages message queues and fan-in detection. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/EdgeRouters/DurableDirectEdgeRouter.cs | Implements direct edge routing with optional conditional evaluation and JSON-based deserialization of predecessor outputs. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableWorkflowServiceCollectionExtensions.cs | Adds ConfigureDurableWorkflows DI extension that configures only workflows via the underlying ConfigureDurableOptions. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableWorkflowRunner.cs | Orchestration runner that executes workflows via message-driven supersteps, dispatching executors and propagating outputs/messages between steps. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableWorkflowRun.cs | Implements IAwaitableWorkflowRun for durable orchestrations using DurableTaskClient and exposes an event sink (not yet wired) for workflow events. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableWorkflowOptions.cs | Adds workflow-specific options: registering named workflows, tracking executors, and auto-registering any referenced agents into DurableAgentsOptions. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableWorkflowJsonContext.cs | Source-generated JSON serialization context for durable workflow payload types (activity input/output, sent messages, state dictionary). |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableWorkflowClient.cs | Implements IWorkflowClient using DurableTaskClient to schedule new orchestration instances and wrap them in DurableWorkflowRun. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableMessageEnvelope.cs | Wraps serialized message payloads with type-name and source-executor metadata for durable routing. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableExecutorDispatcher.cs | Chooses between dispatching an executor as a Durable activity or AI agent, including entity-based execution for agents. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableActivityOutput.cs | Defines the serialized output format from an activity, including result and any sent messages. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableActivityInput.cs | Defines the serialized input format into an activity, including executor input, input type name, and shared state. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableActivityExecutor.cs | Executes a bound executor from serialized durable input, invokes Executor.ExecuteAsync, and returns serialized output plus sent messages. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableActivityContext.cs | Provides an IWorkflowContext implementation for activities, capturing sent messages but currently no-ops for state/events/halt APIs. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/ServiceCollectionExtensions.cs | Switches the durable task data converter registration to the new shared DurableDataConverter. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Microsoft.Agents.AI.DurableTask.csproj | References the Workflows project, enabling durable workflows to use workflow primitives. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/Logs.cs | Adds logging helpers for workflow lifecycle, supersteps, fan-in aggregation, executor results, and agent lookup failures. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/DurableServiceCollectionExtensions.cs | New DI extension entry point for configuring durable agents and workflows, registering orchestrators, activities, entities, and agent services. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/DurableOptions.cs | Introduces root options object combining durable agents and workflows, used by ConfigureDurableOptions. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/DurableDataConverter.cs | Shared DataConverter handling durable agent state via source-generated context and camel-cased JSON for other payloads. |
| dotnet/src/Microsoft.Agents.AI.DurableTask/DurableAgentsOptions.cs | Adds ContainsAgent helper to check whether an agent has already been registered. |
| dotnet/samples/Durable/Workflow/ConsoleApps/02_ConcurrentWorkflow/README.md | Documents the concurrent workflow sample, its fan-out/fan-in pattern, environment configuration, and example output. |
| dotnet/samples/Durable/Workflow/ConsoleApps/02_ConcurrentWorkflow/Program.cs | Sample host wiring a fan-out/fan-in Workflow with 2 class executors and 2 AI agents into Durable Task via ConfigureDurableOptions. |
| dotnet/samples/Durable/Workflow/ConsoleApps/02_ConcurrentWorkflow/ExpertExecutors.cs | Implements the ParseQuestionExecutor and AggregatorExecutor used in the concurrent workflow sample. |
| dotnet/samples/Durable/Workflow/ConsoleApps/02_ConcurrentWorkflow/02_ConcurrentWorkflow.csproj | Project file for the concurrent workflow console sample, referencing core durable/AI projects. |
| dotnet/samples/Durable/Workflow/ConsoleApps/01_SequentialWorkflow/README.md | Documents the sequential cancellation workflow sample and how to demonstrate durability across restarts. |
| dotnet/samples/Durable/Workflow/ConsoleApps/01_SequentialWorkflow/Program.cs | Sample host wiring a 3-step order-cancellation Workflow into Durable Task via ConfigureDurableWorkflows. |
| dotnet/samples/Durable/Workflow/ConsoleApps/01_SequentialWorkflow/OrderCancelExecutors.cs | Defines the OrderLookup, OrderCancel, and SendEmail executors used by the sequential workflow sample. |
| dotnet/samples/Durable/Workflow/ConsoleApps/01_SequentialWorkflow/01_SequentialWorkflow.csproj | Project file for the sequential workflow console sample, referencing durable task and agent projects. |
| dotnet/agent-framework-dotnet.slnx | Adds the new durable workflow sample projects to the .NET solution. |
Additional note: Because this PR changes dotnet/src/Microsoft.Agents.AI.DurableTask/**, it likely needs a new bullet under the [Unreleased] section of dotnet/src/Microsoft.Agents.AI.DurableTask/CHANGELOG.md per the repo’s durable-task instructions.
dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableActivityContext.cs
Show resolved
Hide resolved
| private readonly List<WorkflowEvent> _eventSink = []; | ||
| private int _lastBookmark; | ||
|
|
||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="DurableWorkflowRun"/> class. | ||
| /// </summary> | ||
| /// <param name="client">The durable task client for orchestration operations.</param> | ||
| /// <param name="instanceId">The unique instance ID for this orchestration run.</param> | ||
| /// <param name="workflowName">The name of the workflow being executed.</param> | ||
| internal DurableWorkflowRun(DurableTaskClient client, string instanceId, string workflowName) | ||
| { | ||
| this._client = client; | ||
| this.RunId = instanceId; | ||
| this.WorkflowName = workflowName; | ||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public string RunId { get; } | ||
|
|
||
| /// <summary> | ||
| /// Gets the name of the workflow being executed. | ||
| /// </summary> | ||
| public string WorkflowName { get; } | ||
|
|
||
| /// <summary> | ||
| /// Waits for the workflow to complete and returns the result. | ||
| /// </summary> | ||
| /// <typeparam name="TResult">The expected result type.</typeparam> | ||
| /// <param name="cancellationToken">A cancellation token to observe.</param> | ||
| /// <returns>The result of the workflow execution.</returns> | ||
| /// <exception cref="InvalidOperationException">Thrown when the workflow failed or was terminated.</exception> | ||
| public async ValueTask<TResult?> WaitForCompletionAsync<TResult>(CancellationToken cancellationToken = default) | ||
| { | ||
| OrchestrationMetadata metadata = await this._client.WaitForInstanceCompletionAsync( | ||
| this.RunId, | ||
| getInputsAndOutputs: true, | ||
| cancellation: cancellationToken).ConfigureAwait(false); | ||
|
|
||
| if (metadata.RuntimeStatus == OrchestrationRuntimeStatus.Completed) | ||
| { | ||
| return metadata.ReadOutputAs<TResult>(); | ||
| } | ||
|
|
||
| if (metadata.RuntimeStatus == OrchestrationRuntimeStatus.Failed) | ||
| { | ||
| string errorMessage = metadata.FailureDetails?.ErrorMessage ?? "Workflow execution failed."; | ||
| throw new InvalidOperationException(errorMessage); | ||
| } | ||
|
|
||
| throw new InvalidOperationException($"Workflow ended with unexpected status: {metadata.RuntimeStatus}"); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Waits for the workflow to complete and returns the string result. | ||
| /// </summary> | ||
| /// <param name="cancellationToken">A cancellation token to observe.</param> | ||
| /// <returns>The string result of the workflow execution.</returns> | ||
| public ValueTask<string?> WaitForCompletionAsync(CancellationToken cancellationToken = default) | ||
| => this.WaitForCompletionAsync<string>(cancellationToken); | ||
|
|
||
| /// <summary> | ||
| /// Gets all events that have been collected from the workflow. | ||
| /// </summary> | ||
| public IEnumerable<WorkflowEvent> OutgoingEvents => this._eventSink; | ||
|
|
||
| /// <summary> | ||
| /// Gets the number of events collected since the last access to <see cref="NewEvents"/>. | ||
| /// </summary> | ||
| public int NewEventCount => this._eventSink.Count - this._lastBookmark; | ||
|
|
||
| /// <summary> | ||
| /// Gets all events collected since the last access to <see cref="NewEvents"/>. | ||
| /// </summary> | ||
| public IEnumerable<WorkflowEvent> NewEvents | ||
| { | ||
| get | ||
| { | ||
| if (this._lastBookmark >= this._eventSink.Count) | ||
| { | ||
| return []; | ||
| } | ||
|
|
||
| int currentBookmark = this._lastBookmark; | ||
| this._lastBookmark = this._eventSink.Count; | ||
|
|
||
| return this._eventSink.Skip(currentBookmark); | ||
| } | ||
| } |
There was a problem hiding this comment.
DurableWorkflowRun exposes OutgoingEvents/NewEvents and maintains an _eventSink, but no code ever appends to this list, so callers will always see zero events even if executors call IWorkflowContext.AddEventAsync.
To make the event-tracking APIs useful, you either need to plumb workflow events from the durable execution path into this sink (similar to Run in Microsoft.Agents.AI.Workflows), or clearly document/guard that durable runs do not yet support event streaming.
There was a problem hiding this comment.
This is intentional. The next PR will use this in a meaningful way. I wanted to keep the props for now.
dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableWorkflowRunner.cs
Show resolved
Hide resolved
| foreach (WorkflowRegistrationInfo registration in registrations) | ||
| { | ||
| registry.AddOrchestratorFunc<string, string>( | ||
| registration.OrchestrationName, | ||
| (context, input) => RunWorkflowOrchestrationAsync(context, input, durableOptions)); | ||
|
|
There was a problem hiding this comment.
The worker registration hard-codes orchestrator input and output types as string (AddOrchestratorFunc<string, string>), but IWorkflowClient.RunAsync<TInput> allows arbitrary TInput, so any non-string input will be serialized using DurableDataConverter and then deserialized back into a string before entering DurableWorkflowRunner.
This effectively ignores the generic TInput type and makes non-string inputs fragile or unusable; consider either constraining RunAsync to string input or updating the orchestrator registration and DurableWorkflowRunner to honor the actual input type (including propagating its type name into the initial DurableMessageEnvelope).
dotnet/samples/Durable/Workflow/ConsoleApps/01_SequentialWorkflow/OrderCancelExecutors.cs
Show resolved
Hide resolved
dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableWorkflowRunner.cs
Outdated
Show resolved
Hide resolved
| { | ||
| this._outputHelper.WriteLine("Starting shared DTS infrastructure..."); | ||
| await this.StartDtsEmulatorAsync(); | ||
| s_dtsInfrastructureStarted = true; |
There was a problem hiding this comment.
Write to static field from instance method, property, or constructor.
dotnet/tests/Microsoft.Agents.AI.DurableTask.IntegrationTests/SamplesValidationBase.cs
Outdated
Show resolved
Hide resolved
dotnet/samples/Durable/Workflow/ConsoleApps/02_ConcurrentWorkflow/ExpertExecutors.cs
Show resolved
Hide resolved
dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/EdgeRouters/DurableEdgeMap.cs
Show resolved
Hide resolved
cgillum
left a comment
There was a problem hiding this comment.
Some initial comments. I'm not yet done reviewing.
| object? messageObj = DeserializeForCondition(envelope.Message, this._sourceOutputType); | ||
| if (!this._condition(messageObj)) | ||
| { | ||
| if (logger.IsEnabled(LogLevel.Debug)) |
There was a problem hiding this comment.
Should we use source-generated logging so that we don't need to add all this boilerplate?
There was a problem hiding this comment.
Yea, missed these. Updated now to use source gen logging.
| } | ||
| catch (JsonException) | ||
| { | ||
| return json; |
There was a problem hiding this comment.
When is this case expected? Can you add comments?
There was a problem hiding this comment.
Not really needed. I kept it as defensive fallback just in case the input is something which fails to deserialize. Removed now. Let the error bubble up.
| /// <inheritdoc/> | ||
| public ValueTask YieldOutputAsync( | ||
| object output, | ||
| CancellationToken cancellationToken = default) => default; |
There was a problem hiding this comment.
Why are we returning default for all these methods. Can you please add comments explaining?
There was a problem hiding this comment.
Sorry. I forgot to add that comment. But yes, in this first PR I am returning default. The follow up PRs will add implementation for these. Events (YieldOutputAsync uses events) support is coming in follow up PR.
There was a problem hiding this comment.
I also added a comment to this file. But the next PR will have implementation of these methods.
|
|
||
| string serializedInput = JsonSerializer.Serialize(activityInput, DurableWorkflowJsonContext.Default.DurableActivityInput); | ||
|
|
||
| return await context.CallActivityAsync<string>(activityName, serializedInput).ConfigureAwait(true); |
There was a problem hiding this comment.
Add a comment explaining why we do .ConfigureAwait(true) since most people reading this code won't intuitively understand.
There was a problem hiding this comment.
Added comments to relevant files explaining why we do .ConfigureAwait(true).
| /// </summary> | ||
| /// <remarks> | ||
| /// <para> | ||
| /// This is the durable equivalent of <c>MessageEnvelope</c> in the in-process runner. |
There was a problem hiding this comment.
Is MessageEnvelope public? If so, prefer <see href="..."> instead of <c> so that you get the benefits of compiler warnings if this type can't be found or is renamed in the future.
There was a problem hiding this comment.
MessageEnvelope is internal as of today.
dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableWorkflowClient.cs
Outdated
Show resolved
Hide resolved
dotnet/src/Microsoft.Agents.AI.DurableTask/Workflows/DurableWorkflowOptions.cs
Outdated
Show resolved
Hide resolved
cgillum
left a comment
There was a problem hiding this comment.
Great start on this! I finished my first full round. Added a few comments below. Overall, I'm good with the direction.
| if (metadata.RuntimeStatus == OrchestrationRuntimeStatus.Failed) | ||
| { | ||
| string errorMessage = metadata.FailureDetails?.ErrorMessage ?? "Workflow execution failed."; | ||
| throw new InvalidOperationException(errorMessage); |
There was a problem hiding this comment.
There's a lot of information we're throwing away here. Unless InvalidOperationException is a required part of the API contract, I suggest an exception that contains more information, such as TaskFailedException, which allows you to pass in that FailureDetails object in the line above this one. If you go with that approach, just use a dummy value 0 for taskId.
| /// <remarks> | ||
| /// This method provides a workflow-focused configuration experience. | ||
| /// If you need to configure both agents and workflows, consider using | ||
| /// <see cref="DurableServiceCollectionExtensions.ConfigureDurableOptions"/> instead. |
There was a problem hiding this comment.
Do we have a similar actors-only API for parity? Can both ConfigureDurableWorkflows and ConfigureDurableOptions be used together?
| /// <param name="executorName">The executor name to look up.</param> | ||
| /// <param name="registration">When this method returns, contains the registration if found; otherwise, null.</param> | ||
| /// <returns><see langword="true"/> if the executor was found; otherwise, <see langword="false"/>.</returns> | ||
| internal bool TryGetExecutor(string executorName, out ExecutorRegistration? registration) |
There was a problem hiding this comment.
Use [NotNullWhen(true)] on the registration parameter for improved nullability checks.
| /// <summary> | ||
| /// Represents a running instance of a workflow. | ||
| /// </summary> | ||
| public interface IWorkflowRun |
There was a problem hiding this comment.
Does the core workflow MAF library not have an abstraction for workflow runs?
| /// <param name="IsAgenticExecutor">Indicates whether this executor is an agentic executor.</param> | ||
| /// <param name="RequestPort">The request port if this executor is a request port executor; otherwise, null.</param> | ||
| /// <param name="SubWorkflow">The sub-workflow if this executor is a sub-workflow executor; otherwise, null.</param> | ||
| internal sealed record WorkflowExecutorInfo( |
There was a problem hiding this comment.
I didn't expect to find a class like this in a file named WorkflowAnalyzer.cs. Should it go into it's own file?
| /// <summary> | ||
| /// Extension methods for configuring durable agents and workflows with dependency injection. | ||
| /// </summary> | ||
| public static class DurableServiceCollectionExtensions |
There was a problem hiding this comment.
Do we need both this and ServiceCollectionExtensions.cs or should we have just one?
Motivation and Context
This PR adds durable workflow support to the Agent Framework, enabling workflows to run as Durable Task orchestrations. This addresses the need for long-running, reliable workflow execution that can survive process restarts, handle failures gracefully, and supports distributed workflow execution across multiple nodes.
Key scenarios enabled:
Description
This PR introduces a new set of public APIs for running workflows as Durable Task orchestrations.
New Public APIs
Workflow Execution Interfaces
IWorkflowRunIAwaitableWorkflowRunIWorkflowRunwith completion awaiting capabilityIWorkflowClientConfiguration Options
DurableOptionsDurableWorkflowOptionsService Collection Extensions
ConfigureDurableOptionsConfigureDurableWorkflowsUsage Examples
Sequential Workflow (Sample:
01_SequentialWorkflow)Fan-out/Fan-in Workflow (Sample:
02_ConcurrentWorkflow)Conditional Edges Workflow (Sample:
03_ConditionalEdges)Validation/Testing
Samples Added:
samples/Durable/Workflow/ConsoleApps/01_SequentialWorkflowsamples/Durable/Workflow/ConsoleApps/02_ConcurrentWorkflowsamples/Durable/Workflow/ConsoleApps/03_ConditionalEdgesIntegration Tests: Integration tests have been added to run and validate the sample workflows, ensuring end-to-end functionality works as expected.
Contribution Checklist