Skip to content

fix(directory): wait for active membership during startup - #10613

Merged
ReubenBond merged 4 commits into
dotnet:mainfrom
ReubenBond:rb-fix-startup-task-directory-race
Aug 18, 2026
Merged

ReubenBond merged 4 commits into
dotnet:mainfrom
ReubenBond:rb-fix-startup-task-directory-race

Conversation

@ReubenBond

@ReubenBond ReubenBond commented Aug 15, 2026

Copy link
Copy Markdown
Member

Fixes #10600

Problem

Startup tasks run after cluster membership reports the silo as active, but the distributed grain directory can briefly lag on a joining-only view with no active directory owners. That transient view was treated as terminal, returning a null registration result and invalidating the new activation.

Solution

Wait for the directory view to catch up when the latest cluster membership still contains an active member. Preserve the existing terminal behavior when the cluster truly has no active members, including shutdown. Add a deterministic regression which holds directory membership on a joining-only view and verifies owner resolution resumes after the active view is published.

Rationale

This restores the readiness invariant at the directory operation boundary instead of masking the failure with startup-task retries or delays, while retaining prompt shutdown behavior.

Microsoft Reviewers: Open in CodeFlow

Copilot AI lite review requested due to automatic review settings August 15, 2026 17:23
@ReubenBond
ReubenBond requested a review from jdom August 15, 2026 17:24

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

This PR addresses a startup race in the distributed grain directory where directory membership can temporarily lag behind cluster membership (showing a joining-only/empty directory view even though the silo is already active), causing transient null owner/registration results and invalid activations. It updates the runtime to wait for an owner-bearing directory view when cluster membership still has an active member, and adds a deterministic regression test which simulates the lagging membership view.

Changes:

  • Add GetViewWithOwnerAsync to wait for a directory membership view which can resolve an owner when cluster membership still contains an active silo.
  • Refactor DirectoryMembershipService to expose an internal PublishMembershipUpdate helper (used by the service loop and the new test).
  • Add a new BVT test which forces a joining-only directory membership view and verifies owner resolution resumes once an active view is published.
Show a summary per file
File Description
test/Orleans.GrainDirectory.Tests/GrainDirectory/DistributedGrainDirectoryTests.cs Adds a deterministic regression test for directory membership lag during startup.
src/Orleans.Runtime/GrainDirectory/DistributedGrainDirectory.cs Waits for an owner-bearing directory membership view when cluster membership still has active members; adds test hook.
src/Orleans.Runtime/GrainDirectory/DirectoryMembershipService.cs Extracts membership update publishing into an internal method to support deterministic 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: 1
  • Review effort level: Lite

Copilot AI review requested due to automatic review settings August 16, 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.

src/Orleans.Runtime/GrainDirectory/DistributedGrainDirectory.cs:253

  • GetViewWithOwnerAsync(...) only returns after view.TryGetOwner(grainId, ...) succeeds (it’s part of that helper’s loop condition), so this TryGetOwner/throw is effectively an invariant check and should be unreachable. Consider refactoring GetViewWithOwnerAsync to return (view, owner, partitionReference) so the owner is computed once and the invariant is expressed in one place (avoids duplicate ring lookups and removes an unreachable branch here).
            view = resolvedView;
            if (!view.TryGetOwner(grainId, out var owner, out var partitionReference))
            {
                throw new InvalidOperationException($"Directory membership view {view.Version} does not have an owner for grain '{grainId}'.");
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

ReubenBond and others added 3 commits August 17, 2026 14:55
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f2fdec36-8ebf-4708-9061-b5e3a1055d4c
Copilot AI review requested due to automatic review settings August 17, 2026 22:08
@ReubenBond
ReubenBond force-pushed the rb-fix-startup-task-directory-race branch from 8c4dcfc to b931fda Compare August 17, 2026 22:08

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: Lite

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f2fdec36-8ebf-4708-9061-b5e3a1055d4c
Copilot AI review requested due to automatic review settings August 17, 2026 22:51

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: 2/2 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

This was referenced Sep 7, 2026
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.

Flaky test: startup task grain call fails directory registration

2 participants