perf(codegen): generate provider metadata at build time - #10493
Conversation
da5e334 to
0a50c96
Compare
|
I audited the incremental-generator impact and pushed A three-way BenchmarkDotNet comparison used |
There was a problem hiding this comment.
Pull request overview
This PR shifts RegisterProviderAttribute interpretation into the Orleans incremental source-generator pipeline, emitting lightweight build-time provider metadata and updating client/silo configuration to resolve providers via a shared runtime resolver.
Changes:
- Introduces
IProviderMetadataProviderand generates implementations only when provider metadata exists. - Adds
ProviderRegistrationResolverand routes both client and silo provider resolution through it (with legacy attribute fallback for older assemblies). - Extends codegen models/tests to extract, normalize, and cache provider registration metadata deterministically.
Show a summary per file
| File | Description |
|---|---|
| test/Orleans.Core.Tests/ProviderRegistrationResolverTests.cs | Adds coverage for generated metadata consumption, legacy fallback, and non-activation of custom manifest providers. |
| test/Orleans.CodeGenerator.Tests/ModelExtractorTests.cs | Verifies provider registrations are extracted (and deterministically ordered) during reference extraction. |
| test/Orleans.CodeGenerator.Tests/IncrementalModelEqualityTests.cs | Extends reference assembly model builder to include provider registrations. |
| test/Orleans.CodeGenerator.Tests/IncrementalCachingTests.cs | Adds incremental caching tests to ensure provider changes invalidate the pipeline and unrelated changes do not. |
| src/Orleans.Serialization/Configuration/ITypeManifestProvider.cs | Introduces the new public IProviderMetadataProvider contract in the serialization configuration namespace. |
| src/Orleans.Runtime/Hosting/DefaultSiloServices.cs | Switches silo provider registration resolution to ProviderRegistrationResolver. |
| src/Orleans.Core/Core/ProviderRegistrationResolver.cs | Adds shared runtime resolver for provider registrations (generated metadata + legacy fallback). |
| src/Orleans.Core/Core/DefaultClientServices.cs | Switches client provider registration resolution to ProviderRegistrationResolver. |
| src/Orleans.CodeGenerator/ReferenceAssemblyDataProvider.cs | Ensures empty reference model includes an empty provider-registration collection. |
| src/Orleans.CodeGenerator/Model/ReferenceAssemblyModelExtractor.cs | Extracts RegisterProviderAttribute metadata and adds it to the reference model with deterministic ordering. |
| src/Orleans.CodeGenerator/Model/ReferenceAssemblyModel.cs | Adds RegisteredProviderModel and stores it on ReferenceAssemblyModel. |
| src/Orleans.CodeGenerator/Model/MetadataAggregateModelBuilder.cs | Normalizes/uniquifies provider registrations for stable incremental caching. |
| src/Orleans.CodeGenerator/MetadataGenerator.cs | Emits IProviderMetadataProvider.ConfigureProviders(...) only when provider registrations exist. |
| src/Orleans.CodeGenerator/LibraryTypes.cs | Adds RegisterProviderAttribute to known library types for extraction. |
| src/api/Orleans.Serialization/Orleans.Serialization.cs | Updates public API surface to include IProviderMetadataProvider. |
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: 15/15 changed files
- Comments generated: 1
- Review effort level: Lite
ae7a554 to
9adc458
Compare
There was a problem hiding this comment.
Review details
Suppressed comments (2)
src/Orleans.Serialization/Configuration/TypeManifestProviderAttribute.cs:37
- Same trimming annotation issue as the constructor parameter: ProviderType is consumed for DI registration and should preserve all public constructors.
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
public Type ProviderType { get; }
src/Orleans.Serialization/Configuration/TypeManifestProviderAttribute.cs:18
- TypeManifestProviderAttribute.ProviderType is used as an implementation type for DI (SerializerBuilderExtensions.AddAssembly registers it with AddSingleton), so trimming needs to preserve all public constructors, not just a public parameterless ctor. Using PublicParameterlessConstructor here can lead to incorrect trimming annotations and ILLink warnings for custom providers with injected constructors.
This issue also appears on line 36 of the same file.
public TypeManifestProviderAttribute(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
Type providerType)
- Files reviewed: 16/16 changed files
- Comments generated: 1
- Review effort level: Lite
Port provider registration discovery to the current incremental reference-assembly model and consume generated manifest metadata during client and silo configuration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Retain constructed generic provider types in generated registrations and avoid executing non-OrleansCodeGen manifest providers while collecting provider metadata. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Preserve closed generic provider types, avoid activating custom manifest providers outside DI, and retain a legacy fallback for packages built with older generators. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: dd22afa0-8eac-4b78-bc16-d2f60bc3cb22
Avoid executing full serialization manifests when resolving configuration-driven providers. Generate a lightweight provider metadata contract, preserve legacy attribute fallback, and cover client, silo, and custom-provider behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 90ba28fa-3faa-4c32-a712-d8cb4b5fd3f0
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 90ba28fa-3faa-4c32-a712-d8cb4b5fd3f0
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 90ba28fa-3faa-4c32-a712-d8cb4b5fd3f0
9adc458 to
1093681
Compare
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 90ba28fa-3faa-4c32-a712-d8cb4b5fd3f0
Problem
Configuration-driven providers are declared with
RegisterProviderAttribute. Resolving them entirely from those attributes at runtime requires assembly enumeration and reflection, and the original implementation in #9731 predates the incremental source-generator architecture.Solution
IProviderMetadataProviderimplementation only when complete provider metadata can be represented safely in generated C#.RegisterProviderAttributefallback.This PR moves provider attribute interpretation to build time and avoids full manifest configuration during provider discovery. It still enumerates relevant assemblies and reflects over
TypeManifestProviderAttributeto locate generated metadata. #10504 tracks a generated module-initializer registry which will remove that remaining reflection from the normal path while retaining lazy compatibility fallback.This supersedes #9731 and fixes #9730.
Microsoft Reviewers: Open in CodeFlow