Skip to content

perf: cache interface identities and serialization dependencies - #11467

Merged
ReubenBond merged 7 commits into
dotnet:mainfrom
ReubenBond:rb-interface-and-proxy-caching
Oct 11, 2026
Merged

ReubenBond merged 7 commits into
dotnet:mainfrom
ReubenBond:rb-interface-and-proxy-caching

Conversation

@ReubenBond

@ReubenBond ReubenBond commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

Grain-reference creation repeatedly formats interface identities and resolves serialization dependencies, adding work for each proxy instance.

Cache successful interface identities per resolver and CLR interface type, including exact closed generic arguments. The generated-code helper delegates built-in provider requests to CodecProvider.GetService. Registered implementations use the provider's existing cache keyed by closed implementation type. Interface holders and other dependencies resolve through Services, preserving construction-provider routing and external-DI restrictions inside closed factory graphs. Implementation activation remains private to the provider.

Generated proxy fields and copier call sites retain their concrete types. ProxyGenerator and its existing snapshots match main. Ordinary dependency-injection lifetimes and serializer factory publication/failure semantics are preserved. The resolver cache remains unchanged from the original version of this PR.

Review found a capturing construction lambda allocating 40 bytes even on cache hits. Construction state now lives in a static miss helper, and warm lookups precede manifest classification. Exact tests measure zero allocated bytes and zero dependency constructions for 1000 warm helper calls on .NET 8/10, with and without closed factories. Direct uncached activation of the tested generated copier allocates 32,096 bytes on .NET 10 and 64,096 bytes on .NET 8 while invoking 1000 constructors. Cached interface lookups allocate zero bytes versus 3,272,000 bytes for 1000 uncached convention lookups in the tested closed-generic workload. These are allocation measurements, not throughput claims.

The service cache retains completed implementations and dependency graphs for provider lifetime; the resolver retains entries for the distinct CLR interfaces it sees. Ordinary concurrent cold resolution can construct multiple candidates and returns the published instance. Closed factories retain their coordinated publication and failure semantics. The implementation reuses the existing service cache and construction machinery.

Behavioral coverage includes concrete reuse across providers, helper-first/provider-first resolution, closed generic proxies, shared references and cycles, override semantics, failure/retry, concurrent publication, and DI lifetimes. Closed-factory regressions exercise all six serialization holder contracts, provider interfaces, rollback after failure, and rejection of external DI before publication. The automated coverage comment describes superseded head 748d784080 (83.39% whole-repository lines); current affected-code coverage remains pending refreshed CI.

Originally extracted from 48f3aaa47fc18123db4109063af591f315e6f9cb through source 9c1ef0f2feb258c1764de5f408d89c53e7e63f9f, then revised in review and rebased onto main b3b76e2ab207f00e664e0167cd733800cd60379d. Public API signatures and serialization identities remain unchanged.

Microsoft Reviewers: Open in CodeFlow

Copilot AI balanced review requested due to automatic review settings October 10, 2026 16:01

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.

🟢 Approval recommended

The implementation is focused, preserves public APIs, and has comprehensive targeted coverage.

0 open findings

What changed in this PR

Caches grain interface identities and resolves generated proxy copiers through provider-managed contracts to reduce proxy construction overhead.

Changes:

  • Adds per-resolver interface identity caching.
  • Generates provider-resolved IDeepCopier<T> proxy fields.
  • Adds focused runtime, generator, concurrency, and documentation coverage.
File Description
src/​Orleans.Core/​Manifest/​GrainInterfaceTypeResolver.cs Caches successful interface identities.
src/​Orleans.CodeGenerator/​ProxyGenerator.cs Resolves copier contracts through CodecProvider.
test/​Orleans.Core.Tests/​Manifest/​GrainInterfaceTypeResolverTests.cs Tests identity caching behavior.
test/​Orleans.Serialization.UnitTests/​ProxyCopierResolutionTests.cs Tests copier reuse and resolution semantics.
test/​Orleans.CodeGenerator.Tests/​ProxyCopierResolutionTests.cs Verifies generated copier contracts.
test/​Orleans.CodeGenerator.Tests/​snapshots/​OrleansSourceGeneratorTests.TestGrainComplexGrain.verified.cs Updates generated proxy snapshot.
docs/​site/​src/​content/​docs/​implementation/​serialization.md Documents identity and copier caching.

🧠 Review effort: Balanced


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

@github-actions

github-actions Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Code coverage

Metric Pull request
Lines 83.42% (118,504 / 142,062)
Branches 73.01% (35,260 / 48,292)

Report-only conclusion: current-main baseline stale.

The newest successful coverage run tested 4268237, not current main bfe0e81.

Coverage combines every CI test matrix job, including providers, CodeGen, .NET 8/10, Linux, Windows, and macOS, using canonical physical source and branch identities.

The comparison remains report-only while normal line and branch variance is calibrated.

Coverage details

Copilot AI balanced review requested due to automatic review settings October 10, 2026 16:43
@ReubenBond ReubenBond changed the title perf(core): cache interface identities and proxy copier dependencies perf: cache interface identities and concrete copier dependencies Oct 10, 2026

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.

🔵 Needs a closer look

Shared serializer construction, failure recovery, and concurrent cache publication warrant final human validation.

0 open findings

🧠 Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 10, 2026 17:28
@ReubenBond ReubenBond changed the title perf: cache interface identities and concrete copier dependencies perf: cache interface identities and serialization dependencies Oct 10, 2026

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.

🔵 Needs a closer look

Core serialization construction, caching, DI lifetime, and concurrency semantics warrant final human review.

0 open findings

🧠 Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 10, 2026 18:00
@ReubenBond
ReubenBond force-pushed the rb-interface-and-proxy-caching branch from d50cd91 to dfaa943 Compare October 10, 2026 18:00

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.

🟡 Changes recommended

Public registration and provider-extension contracts need to document the new lifetime and stability requirements.

2 open findings

🧠 Review effort: Balanced

Comment thread src/Orleans.Core/Manifest/GrainInterfaceTypeResolver.cs
Comment thread src/Orleans.Serialization/Serializers/CodecProvider.cs
Copilot AI balanced review requested due to automatic review settings October 11, 2026 00:12

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.

🟡 Changes recommended

Interface-typed serialization dependencies can fail when resolved from an active closed-factory construction graph.

1 open finding
2 resolved since last review

🧠 Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 11, 2026 00:40

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.

🔵 Needs a closer look

Core serialization construction and concurrency semantics change, while refreshed affected-code coverage remains pending.

1 open finding

🧠 Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 11, 2026 14:30

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.

🔵 Needs a closer look

The changes affect serialization lifetime and concurrency invariants, and refreshed CI remains in progress.

0 open findings

1 resolved since last review

🧠 Review effort: Balanced

@ReubenBond
ReubenBond merged commit bfe0e81 into dotnet:main Oct 11, 2026
89 checks passed
@ReubenBond
ReubenBond deleted the rb-interface-and-proxy-caching branch October 11, 2026 14:49
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