Skip to content

refactor(runtime): start grain activation synchronously - #10569

Draft
ReubenBond wants to merge 29 commits into
dotnet:mainfrom
ReubenBond:rb-start-activation-synchronously
Draft

ReubenBond wants to merge 29 commits into
dotnet:mainfrom
ReubenBond:rb-start-activation-synchronously

Conversation

@ReubenBond

@ReubenBond ReubenBond commented Aug 12, 2026 •

Copy link
Copy Markdown
Member

Follow-up to #10565 and completion of the fix for #10556. This PR builds on the grain-context configuration contract merged in #10565.

IGrainContext now exposes a one-shot startup contract directly: Start() returns a release token and Abort() cleans up an unstarted context. Built-in activation creation configures the context with scheduler execution reserved, publishes or wires it, then calls Start() 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 ExecutionContext so ambient request and transaction AsyncLocal values do not leak into grain construction. DefaultExecutionContext captures a clean context using ThreadPool.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 both net8.0 and net10.0.

Microsoft Reviewers: Open in CodeFlow

@ReubenBond
ReubenBond force-pushed the rb-start-activation-synchronously branch from 116e4c6 to f496298 Compare August 12, 2026 20:13
@ReubenBond
ReubenBond force-pushed the rb-start-activation-synchronously branch from f496298 to 908c934 Compare August 19, 2026 22:48
@ReubenBond
ReubenBond changed the base branch from rb-fix-grain-context-configuration-race to main August 19, 2026 22:48
Copilot AI lite review requested due to automatic review settings August 19, 2026 22:52

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 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 current RuntimeContext.
  • Introduce DefaultExecutionContext to obtain an ambient-state-free ExecutionContext (CoreCLR fast-path via UnsafeAccessor, with a portable fallback).
  • Add focused tests covering scheduler affinity + ambient isolation during activation and validating DefaultExecutionContext behavior (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

Copilot AI review requested due to automatic review settings August 20, 2026 00:07

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: 4/4 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread src/Orleans.Runtime/Activation/ActivationDataActivatorProvider.cs Outdated
Copilot AI review requested due to automatic review settings August 20, 2026 03:32

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

Comment thread src/Orleans.Runtime/Utils/DefaultExecutionContext.cs
Copilot AI review requested due to automatic review settings August 20, 2026 03:39
@ReubenBond
ReubenBond force-pushed the rb-start-activation-synchronously branch from a868ced to 98d1b19 Compare August 20, 2026 03: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.

Review details

  • Files reviewed: 7/7 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

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: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread test/Orleans.Core.Tests/SchedulerTests/OrleansTaskSchedulerBasicTests.cs Outdated
Copilot AI review requested due to automatic review settings August 20, 2026 05:14
@ReubenBond
ReubenBond force-pushed the rb-start-activation-synchronously branch from b116a4f to d547e26 Compare August 20, 2026 05:14

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

Copilot AI review requested due to automatic review settings August 20, 2026 10: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.

Review details

  • Files reviewed: 11/11 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

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
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: ae2e4673-3220-4e33-9073-c2dd36d0fed9
Copilot AI review requested due to automatic review settings September 13, 2026 15:04
@ReubenBond
ReubenBond force-pushed the rb-start-activation-synchronously branch from cf9ad5d to ca17c11 Compare September 13, 2026 15:04

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.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

Review tier: Lite
Findings: 2 High severity · 1 Medium severity

Open findings (3)

Comment on lines +151 to +162
static state =>
{
var context = (ActivationData)state!;
var task = new Task(
static state => ((ActivationData)state!).StartCore(),
context,
CancellationToken.None,
TaskCreationOptions.DenyChildAttach);
context._startup!.RunConstructor(task);
task.GetAwaiter().GetResult();
},
this);
{
// If this is a new worker and there is a message in scope, try to get the request context and activate the worker
var requestContext = (message as Message)?.RequestContextData ?? [];
newWorker.Activate(requestContext, CancellationToken.None);

Assert.DoesNotContain(
collector.GetMeasurementSnapshot(),
measurement => Equals(measurement.Tags["type"], grainTypeName));

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