refactor(runtime): start grain activation synchronously - #10569
Open
ReubenBond wants to merge 28 commits into
Open
refactor(runtime): start grain activation synchronously#10569ReubenBond wants to merge 28 commits into
ReubenBond wants to merge 28 commits into
Conversation
ReubenBond
force-pushed
the
rb-start-activation-synchronously
branch
from
August 12, 2026 20:13
116e4c6 to
f496298
Compare
ReubenBond
force-pushed
the
rb-start-activation-synchronously
branch
from
August 19, 2026 22:48
f496298 to
908c934
Compare
ReubenBond
changed the base branch from
rb-fix-grain-context-configuration-race
to
main
August 19, 2026 22:48
Contributor
There was a problem hiding this comment.
Pull request overview
This PR refactors Orleans runtime grain activation startup so that activation begins synchronously on the activation scheduler before GrainContextActivator.CreateInstance returns, while ensuring the transition runs under a clean ExecutionContext to prevent AsyncLocal/ambient state leakage into grain construction/activation.
Changes:
- Start activation synchronously on the activation scheduler using
Task.RunSynchronously, explicitly installing the activation as the currentRuntimeContext. - Introduce
DefaultExecutionContextto obtain an ambient-state-freeExecutionContext(CoreCLR fast-path viaUnsafeAccessor, with a portable fallback). - Add focused tests covering scheduler affinity + ambient isolation during activation and validating
DefaultExecutionContextbehavior (including concurrent use).
Show a summary per file
| File | Description |
|---|---|
| test/Orleans.Runtime.Tests/GrainActivatorTests.cs | Adds a regression test ensuring synchronous activation start has scheduler affinity, correct RuntimeContext, and no RequestContext/transaction ambient leakage at construction time. |
| test/Orleans.Core.Tests/Runtime/DefaultExecutionContextTests.cs | Adds unit tests validating DefaultExecutionContext contains no ambient state and is safe under concurrent ExecutionContext.Run usage. |
| src/Orleans.Runtime/Utils/DefaultExecutionContext.cs | Adds a utility to obtain an ambient-free ExecutionContext via runtime default or a suppressed-flow capture fallback. |
| src/Orleans.Runtime/Activation/ActivationDataActivatorProvider.cs | Switches activation startup to ExecutionContext.Run(DefaultExecutionContext.Instance, ...) and runs activation start synchronously on the activation task scheduler. |
Review details
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Files reviewed: 4/4 changed files
- Comments generated: 0
- Review effort level: Lite
ReubenBond
force-pushed
the
rb-start-activation-synchronously
branch
from
August 20, 2026 03:39
a868ced to
98d1b19
Compare
ReubenBond
force-pushed
the
rb-start-activation-synchronously
branch
from
August 20, 2026 05:14
b116a4f to
d547e26
Compare
This was referenced Aug 20, 2026
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ae2e4673-3220-4e33-9073-c2dd36d0fed9
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ae2e4673-3220-4e33-9073-c2dd36d0fed9
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ae2e4673-3220-4e33-9073-c2dd36d0fed9
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ae2e4673-3220-4e33-9073-c2dd36d0fed9
ReubenBond
force-pushed
the
rb-start-activation-synchronously
branch
from
August 28, 2026 11:19
9c94dd7 to
cb08b32
Compare
Contributor
There was a problem hiding this comment.
Copilot review overview
Review tier: Lite
Findings: 1
New issues introduced by this change (1)
| Severity | Finding |
|---|---|
src/Orleans.Runtime/Activation/IGrainContextActivator.cs — In PreparedGrainContext.Start(), if startup.Start() throws and startup.Abort() also throws, the… |
Issues resolved since last review (5)
| Severity | Finding |
|---|---|
test/Orleans.Runtime.Internal.Tests/ActivationsLifeCycleTests/ActivationDataMigrationTests.cs — Unused using Orleans.CodeGeneration; will trigger CS8019 (warnings-as-errors). Remove it from… View resolved comment |
|
test/Orleans.Runtime.Internal.Tests/ActivationsLifeCycleTests/ActivationStartupTestFixture.cs — Unused using Orleans.CodeGeneration; will trigger CS8019 (warnings-as-errors). Remove it from… View resolved comment |
|
test/Orleans.Runtime.Internal.Tests/ActivationsLifeCycleTests/ActivationStartupTests.cs — Unused using Orleans.CodeGeneration; will trigger CS8019 (warnings-as-errors). Remove it from… View resolved comment |
|
test/Orleans.Runtime.Internal.Tests/ActivationsLifeCycleTests/StatelessWorkerActivationStartupTests.cs — Unused using Orleans.CodeGeneration; will trigger CS8019 (warnings-as-errors). Remove it from… View resolved comment |
|
test/Orleans.Runtime.Tests/GrainActivatorTests.cs — Unused using directive System.Diagnostics.Metrics will trigger CS8019 (and likely fail the build… View resolved comment |
Contributor
There was a problem hiding this comment.
Copilot review overview
Review tier: Lite
Findings: None
Issues resolved since last review (1)
| Severity | Finding |
|---|---|
src/Orleans.Runtime/Activation/IGrainContextActivator.cs — In PreparedGrainContext.Start(), if startup.Start() throws and startup.Abort() also throws, the… View resolved comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Follow-up to #10565 and completion of the fix for #10556. This PR builds on the grain-context configuration contract merged in #10565.
IGrainContextnow exposes a one-shot startup contract directly:Start()returns a release token andAbort()cleans up an unstarted context. Built-in activation creation configures the context with scheduler execution reserved, publishes or wires it, then callsStart()to construct the grain exactly once under activation scheduler ownership. Rehydration and activation operations are queued before disposing the token releases the prequeued message loop. Failures after construction use normal deactivation and instance disposal.The construction task is created under a clean
ExecutionContextso ambient request and transactionAsyncLocalvalues do not leak into grain construction.DefaultExecutionContextcaptures a clean context usingThreadPool.UnsafeQueueUserWorkItem, failing fast if the work item cannot be queued.Custom eager contexts retain compatibility through the default no-op
Start()/Abort()implementations. Focused regression coverage verifies exactly-once startup, deferred work, abort/reuse, scheduler and runtime-context affinity across asynchronous signals, request and transaction ambient-state isolation, hosted-client streams, duplicate-activation stress, stateless-worker constructor failure, activation tracing, and direct activator behavior on bothnet8.0andnet10.0.Microsoft Reviewers: Open in CodeFlow