Skip to content

fix(runtime): refresh stale empty directory views - #10625

Merged
ReubenBond merged 2 commits into
dotnet:mainfrom
ReubenBond:rb-fix-startup-task-readiness
Aug 17, 2026
Merged

ReubenBond merged 2 commits into
dotnet:mainfrom
ReubenBond:rb-fix-startup-task-readiness

Conversation

@ReubenBond

@ReubenBond ReubenBond commented Aug 16, 2026 •

Copy link
Copy Markdown
Member

Fixes #10600

During silo startup, the distributed grain directory could still hold an empty Joining view after cluster membership had advanced to Active. That stale view was treated as authoritative, so activation registration returned no address and Active-stage startup task grain calls were rejected after forwarding.

Refresh the directory when cluster membership is newer than an empty directory view, while preserving the immediate empty result when the view is current. Add deterministic coverage which holds the directory on a positive-version Joining view until it requests the newer Active view, preserving the supported Active-stage startup task contract without retry-based masking.

Microsoft Reviewers: Open in CodeFlow

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings August 16, 2026 16:36

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.

Pull request overview

Fixes a silo-startup race in the experimental distributed grain directory where an empty Joining directory view could remain cached after cluster membership advanced to Active, causing activation registration to resolve no owner/address and leading to forwarded calls being rejected during Active-stage startup tasks.

Changes:

  • Refreshes the distributed grain directory when an empty directory view is behind the latest observed cluster membership version (while preserving immediate empty results when the view is current).
  • Generalizes DirectoryMembershipService to depend on IClusterMembershipService to enable test-time membership service wrapping.
  • Adds deterministic coverage which holds the directory on a stale Joining membership view until it requests the newer Active view, validating the fix without relying on retries.
Show a summary per file
File Description
test/Orleans.Runtime.Tests/StartupTaskTests.cs Adds deterministic regression coverage by wrapping cluster membership updates to reproduce the stale empty view scenario and asserting a refresh to the Active membership version occurs.
src/Orleans.Runtime/GrainDirectory/DistributedGrainDirectory.cs Avoids treating an empty directory view as authoritative when cluster membership has already advanced beyond that view.
src/Orleans.Runtime/GrainDirectory/DirectoryMembershipService.cs Switches from ClusterMembershipService to IClusterMembershipService to allow substituting membership behavior (primarily for testing).

Review details

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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

Comment thread test/Orleans.Runtime.Tests/StartupTaskTests.cs Outdated
Comment thread test/Orleans.Runtime.Tests/StartupTaskTests.cs
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 17, 2026 09:11

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)

Previously missed (1) — in code that hasn't changed since the last review.

test/Orleans.Runtime.Tests/StartupTaskTests.cs:109

  • Refresh can release the delayed Active membership update before staleDirectoryVersion is initialized (there is a small window after activeUpdateDelayed is set but before staleDirectoryVersion is written in GetMembershipUpdates). If a concurrent Refresh happens in that window, the gate can open early and make the test nondeterministic. Guard against the uninitialized (0) stale version before triggering releaseActiveUpdate.
                    if (Volatile.Read(ref this.activeUpdateDelayed) != 0 && minimumVersion.Value > staleVersion)
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@ReubenBond

Copy link
Copy Markdown
Member Author

The refreshed CI run and two targeted retries show a recurring Azure reminder failure on this head rather than a one-off job issue. Azure Storage
et8.0\ failed in attempt 1, attempt 2, and attempt 3. The repeated cases are \Rem_Azure_UpdateReminder_DoesNotRestartLocalReminder, \Rem_Azure_MultiGrainMultiReminders, and \Rem_Azure_1J_MultiGrainMultiReminders; failures include missed ticks and conflicting tick ownership across two silos. This overlaps the known reminder-suite flake tracked by #10499, but three consecutive failures on this branch mean the Azure
et8.0\ gate remains unresolved and should not be treated as cleared by retry alone.

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

  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@ReubenBond
ReubenBond merged commit bf262f2 into dotnet:main Aug 17, 2026
320 of 329 checks passed
@ReubenBond
ReubenBond deleted the rb-fix-startup-task-readiness branch August 17, 2026 20:08
This was referenced Aug 28, 2026
This was referenced Sep 7, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 17, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flaky test: startup task grain call fails directory registration

2 participants