Skip to content

feat(samples): demonstrate durable Orleans workflows - #10699

Open
ReubenBond wants to merge 137 commits into
dotnet:mainfrom
ReubenBond:rb-turbo-succotash
Open

ReubenBond wants to merge 137 commits into
dotnet:mainfrom
ReubenBond:rb-turbo-succotash

Conversation

@ReubenBond

@ReubenBond ReubenBond commented Aug 20, 2026 •

Copy link
Copy Markdown
Member

Problem

The durable execution stack needs a curated, copyable sample showing how its public APIs compose across Orleans replicas, including recovery, external decisions, compensation, and retained-result observation.

Solution

Adds samples/DurableWorkflows, an Aspire application with two service replicas, Redis membership, and Azurite-backed Journaling and Durable Jobs storage. The sample demonstrates stable root and child identities, durable fan-out/fan-in, human approval, persisted business cancellation, reverse-order saga compensation, and idempotent effects.

Status GETs attach to existing tasks and poll retained results. Missing or expired roots return 404; retained execution failures return a safe failed status, including failures caused by another grain's missing task with the same root ID. Recovery scenarios wait on the original scheduled handle after activation or silo loss.

The sample includes 23 workflow/endpoint cases, gallery registration, standalone project/package declarations, and guidance distinguishing result retention, retained task identity, and message deduplication. Documentation CI builds the local Orleans packages and executes the sample's MTP test application against them, preserving cluster logs for recovery diagnosis.

Package boundary and publication

The alpha Microsoft.Orleans.DurableTasks.Abstractions and Microsoft.Orleans.DurableMessaging foundations participate in normal solution packaging. Sample validation explicitly opts into the incubating Microsoft.Orleans.DurableTasks adapter with PackDurableTaskAdapter=true.

During repository validation, Build-Samples.ps1 selects one unique local package version. samples/Directory.Build.targets applies OrleansSamplePackageVersion to every Microsoft.Orleans.* package reference and central package version. This locks the entire Orleans package family to that source build. The checked-in standalone version declarations identify the individual packages' release channels; repository validation overrides them with the exact local version.

Standalone public-feed restore requires publication of every required package. The adapter's publication decision remains a dependency of this sample's release.

Dependency history

The branch preserves exact audited dependency ancestry and adds sample-only commits above it:

The sample-owned delta from #10696 is restricted to samples/ and its Documentation CI execution and diagnostics steps. Generic Journaling participant and observer regressions remain in the inherited Messaging layer. The PR base stays main so upstream CI runs while the fork dependencies are unmerged.

Copilot AI lite review requested due to automatic review settings August 20, 2026 06:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

Copilot AI review requested due to automatic review settings August 20, 2026 06:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

Copilot AI review requested due to automatic review settings August 20, 2026 06:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

Copilot AI review requested due to automatic review settings August 20, 2026 06:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

Copilot AI review requested due to automatic review settings August 20, 2026 09:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

@ReubenBond

Copy link
Copy Markdown
Member Author

CI failure analysis: Documentation run 32341516041 failed deterministically because the new DurableWorkflows sample restores System.Distributed.DurableTasks, but the sample-validation package feed did not contain that intentionally unpublished project (NU1101). Commit 82ac313 makes the dependency packable only for sample validation and includes its README in the temporary package; the sample build and full solution build now succeed, and fresh CI has been triggered by the push.

Copilot AI review requested due to automatic review settings August 20, 2026 10:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

@ReubenBond

Copy link
Copy Markdown
Member Author

A fresh Documentation run exposed a second PR-specific validation failure after the sample build passed: the generated gallery linked to the DurableWorkflows directory on the main branch before that directory exists there, producing a 404. Commit db02c5d adds the established exact temporary external-link allowlist entry; it will become stale automatically after merge. The complete docs validation and solution build now pass.

Copilot AI review requested due to automatic review settings August 20, 2026 12:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

Copilot AI review requested due to automatic review settings August 20, 2026 12:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

Copilot AI review requested due to automatic review settings August 20, 2026 13:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

Copilot AI review requested due to automatic review settings August 20, 2026 13:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

Copilot AI review requested due to automatic review settings August 20, 2026 18:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

Suppressed comments (1)

src/Orleans.DurableJobs/ShardExecutor.cs:313

  • ResettableJobShardNotSupportedException is excluded from the inner catch, so it bubbles to the outer catch and gets enqueued into taskFailures (causing RunShardAsync to fail the whole shard) instead of being routed through _options.ShouldRetry(...) like other execution failures.

If a job handler accidentally returns RetryAt while using a shard implementation which cannot reschedule, this turns into a shard-level failure rather than a job-level failure with backoff. Consider treating this exception as failureException (so it follows the normal retry/no-retry path) or converting it into a Failed result path with a clear log message.

  • Files reviewed: 140/168 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread src/Microsoft.Orleans.DurableTasks/DurableTaskMessageHandler.cs Outdated
Copilot AI review requested due to automatic review settings August 20, 2026 19:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

Suppressed comments (2)

src/Microsoft.Orleans.DurableTasks/DurableTaskMessageHandler.cs:25

  • IDurableTaskRequest.Context is nullable; using the null-forgiving operator here can turn malformed/mixed-version messages into a NullReferenceException. Consider validating invocation.Request.Context and throwing an InvalidOperationException with a clear message if it's missing.
    src/Microsoft.Orleans.DurableTasks/Storage/DurableTaskHostingExtensions.cs:11
  • #pragma warning disable CS1998 appears unnecessary in this file (there are no async methods). This can trigger IDE0079 ('Remove unnecessary suppression') under analyzers-as-errors.
  • Files reviewed: 137/168 changed files
  • Comments generated: 3
  • Review effort level: Lite

Comment thread src/Microsoft.Orleans.DurableTasks/Runtime/DurableTaskState.cs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

A newly introduced public serialized DTO (DurableTaskDiagnosticState) declares non-nullable reference members which can be null in version-tolerant/default scenarios, requiring an API contract fix (and regenerated API surface).

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 1 Medium severity

New issues introduced by this change (1)
Severity Finding
Medium severity src/​Microsoft.Orleans.DurableTasks/​Protocol/​IDurableTaskGrainRuntime.cs — DurableTaskDiagnosticState is a version-tolerant serialized struct, so reference-typed members…
Suppressed comments (1)

docs/site/src/content/docs/resources/nuget-packages.md:82

  • This table links to https://www.nuget.org/packages/Microsoft.Orleans.DurableMessaging, but the same PR metadata indicates the package is not yet published (and it’s listed as unpublished in docs/site/src/data/unpublished-api-packages.json). Consider removing the NuGet link and explicitly marking the package as awaiting first publication, consistent with the DurableTasks entries above.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

It introduces new runtime infrastructure and public surface area across multiple subsystems (Journaling, Durable Jobs, Durable Messaging, Durable Tasks) in addition to the sample and CI wiring, requiring careful end-to-end validation and human review.

Review tier: Lite
Findings: 2 Medium severity

New issues introduced by this change (2)
Severity Finding
Medium severity samples/​DurableWorkflows/​DurableWorkflows.Service/​WorkflowGrain.cs — RunOrderSagaAsync returns exception.Message in the public OrderWorkflowResult failure field.…
Medium severity src/​Orleans.DurableMessaging/​DurableMessagingActivationValidator.cs — Validate uses reflection + LINQ over all grain interfaces/methods on every activation where…
Issues resolved since last review (1)
Severity Finding
Medium severity src/​Microsoft.Orleans.DurableTasks/​Protocol/​IDurableTaskGrainRuntime.cs — DurableTaskDiagnosticState is a version-tolerant serialized struct, so reference-typed members… View resolved comment

Comment on lines +112 to +117
_ = await inventory.ReleaseAsync($"{request.OrderId}:release").WithId("release-inventory");
compensations.Add("release-inventory");
}

return new(request.OrderId, OrderWorkflowStatus.Compensated, compensations.ToArray(), exception.Message);
}
Comment on lines +27 to +35
var grainInterfaces = grainType
.GetInterfaces()
.Where(static type => typeof(IGrain).IsAssignableFrom(type))
.ToArray();
var interleavableMethod = grainInterfaces
.SelectMany(static type => type.GetInterfaces().Append(type))
.Distinct()
.SelectMany(static type => type.GetMethods())
.FirstOrDefault(static method => method.IsDefined(typeof(AlwaysInterleaveAttribute), inherit: true));

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants