Skip to content

fix(directory): preserve newer recovery registrations - #10533

Merged
ReubenBond merged 4 commits into
dotnet:mainfrom
ReubenBond:rb-fix-rolling-upgrade-directory-race
Aug 12, 2026
Merged

ReubenBond merged 4 commits into
dotnet:mainfrom
ReubenBond:rb-fix-rolling-upgrade-directory-race

Conversation

@ReubenBond

@ReubenBond ReubenBond commented Aug 12, 2026

Copy link
Copy Markdown
Member

During partition recovery, activation responses from live silos were merged using last-writer-wins ordering. In a rolling upgrade, a response from an older LocalGrainDirectory activation could therefore overwrite a registration created in a newer distributed-directory membership view, leaving the recovered directory pointing at the superseded activation.

Prefer recovered registrations with the highest membership version so response order cannot regress directory state. Add deterministic coverage for both response orders.

Fixes #10519

Keep partition recovery responses from replacing registrations created in a newer membership view, regardless of response order.

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

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 rolling-upgrade recovery correctness issue in the distributed grain directory: when merging recovered activation registrations, response ordering could previously regress directory state. The fix makes recovery prefer registrations from the highest cluster membership version and adds a deterministic unit test to cover both response orders.

Changes:

  • Update partition recovery to merge recovered entries by choosing the highest MembershipVersion (instead of last-writer-wins by response order).
  • Introduce GrainDirectoryPartition.RecoverEntry(...) to centralize recovery-merge behavior.
  • Add a unit test to validate recovery outcome is independent of response ordering.
Show a summary per file
File Description
src/Orleans.Runtime/GrainDirectory/GrainDirectoryPartition.cs Changes recovery merge logic to prefer higher MembershipVersion via RecoverEntry.
test/Orleans.GrainDirectory.Tests/GrainDirectory/GrainDirectoryPartitionTests.cs Adds deterministic coverage for recovery merge behavior across both response orders.

Review details

Tip

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

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

Comment thread src/Orleans.Runtime/GrainDirectory/GrainDirectoryPartition.cs
Comment thread test/Orleans.GrainDirectory.Tests/GrainDirectory/GrainDirectoryPartitionTests.cs Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 12, 2026 03:45

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.Runtime/GrainDirectory/GrainDirectoryPartition.cs:792

  • LogTraceRecoveredEntry runs before RecoverEntry, so trace logs will say an entry was “Recovered” even when RecoverEntry ignores it due to an existing entry with a higher MembershipVersion. That can make recovery troubleshooting misleading. Consider logging only when the recovered entry is actually applied to _directory.
                DebugAssertOwnership(current, entry.GrainId);
                LogTraceRecoveredEntry(_logger, entry, current.Version);
                RecoverEntry(_directory, entry);
            }
  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Explain why mixed directory recovery can observe superseded activations and that same-version conflicts remain invalid.

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

Copilot-Session: 4fec7e7f-c494-411f-ab29-08fca4d18191
Clarify that cross-version activation conflicts are expected only while LocalGrainDirectory and DistributedGrainDirectory coexist, without changing same-view tie-breaking.

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

Copilot-Session: 4fec7e7f-c494-411f-ab29-08fca4d18191
Copilot AI review requested due to automatic review settings August 12, 2026 14:13

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

@ReubenBond
ReubenBond merged commit fd89ca4 into dotnet:main Aug 12, 2026
74 checks passed
@ReubenBond
ReubenBond deleted the rb-fix-rolling-upgrade-directory-race branch August 12, 2026 14:55
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 12, 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: rolling upgrade restart reports a directory integrity violation

2 participants