Skip to content

State migration - #9

Closed
egil wants to merge 37 commits into
mainfrom
feature/egil-orleans-statemigration-phase1
Closed

State migration#9
egil wants to merge 37 commits into
mainfrom
feature/egil-orleans-statemigration-phase1

Conversation

@egil

@egil egil commented Feb 25, 2026

Copy link
Copy Markdown
Owner

No description provided.

egil added 30 commits February 24, 2026 22:09
…ng, Egil.Orleans.Storage, and Egil.StronglyTypedPrimitives with package versions and analyzers
Add BenchmarkDotNet perf tests that compare Egil.Orleans.StateMigration against plain System.Text.Json for no-migration scenarios.

Includes minimal and complex state models, source-generated context variants, enveloped vs flattened payload layout benchmarks, and solution migration to .slnx.
Copilot AI review requested due to automatic review settings February 25, 2026 11:06
Comment thread .github/workflows/egil-orleans-statemigration-ci.yml Fixed
Comment thread .github/workflows/egil-orleans-statemigration-ci.yml Fixed

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 introduces a new library, Egil.Orleans.StateMigration, which provides versioned JSON type metadata support for Orleans persistent state migrations. The library enables applications to migrate between different state type versions without embedding migration logic directly in grain implementations.

Changes:

  • Introduces a complete state migration framework with Storage<T> wrapper, IMigrateFrom<,> and IMigrate<,> interfaces for defining migrations
  • Implements System.Text.Json converters supporting both enveloped and flattened payload layouts with optimized hot-path for current-type deserialization
  • Adds comprehensive test suite covering serialization, deserialization, migration scenarios, and Orleans in-process cluster integration
  • Includes performance benchmarks comparing reflection-based and source-generated approaches
  • Provides CI/CD workflow, package configuration, and extensive documentation

Reviewed changes

Copilot reviewed 36 out of 37 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
Egil.Orleans.StateMigration/Directory.Packages.props Central package version management for the new library
Egil.Orleans.StateMigration/version.json Version configuration for Nerdbank.GitVersioning
Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/*.cs Core library implementation including Storage wrapper, migration interfaces, type identity resolution, and DI extensions
Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/SystemTextJson/*.cs JSON converter implementations for both enveloped and flattened payload layouts
Egil.Orleans.StateMigration/test/Egil.Orleans.StateMigration.Tests/*.cs Comprehensive test suite covering serialization, deserialization, migration, and Orleans integration
Egil.Orleans.StateMigration/perf/Egil.Orleans.StateMigration.PerfTests/*.cs BenchmarkDotNet performance tests for hot-path scenarios
Egil.Orleans.StateMigration/README.md Detailed documentation of design decisions, usage examples, and benchmarking guidance
Egil.Orleans.StateMigration/IMPLEMENTATION_PLAN.md Implementation roadmap and TDD execution plan
.github/workflows/egil-orleans-statemigration-ci.yml CI/CD workflow for building, testing, and releasing the package
Egil.StronglyTypedPrimitives/Directory.Packages.props Package version configuration for another project (no functional changes)
Egil.Orleans.Storage/Directory.Packages.props Package version configuration for another project (no functional changes)
Egil.Orleans.EventSourcing/Directory.Packages.props Package version configuration for another project (no functional changes)
Comments suppressed due to low confidence (5)

Egil.Orleans.StateMigration/README.md:1

  • The README title includes "(proposal)" which suggests this is still in a proposal stage. However, the PR includes a full implementation with extensive code. Consider either:
  1. Removing "(proposal)" from the title if this is the final implementation
  2. Adding a note about the implementation status if this is still evolving

This clarity will help users understand whether the library is production-ready.

## Egil.Orleans.StateMigration (proposal)

Egil.Orleans.StateMigration/Directory.Packages.props:18

  • The Microsoft.CodeAnalysis.Common and Microsoft.CodeAnalysis.CSharp package versions (5.0.0) are significantly higher than those used in other projects (4.8.0). While this project targets .NET 10, the comment in other projects indicates "Version 4.8.0 matches with the release of dotnet 8". Since this is targeting .NET 10, version 5.0.0 may be appropriate, but consider whether this version is stable and tested, or if alignment with repository conventions is more important for maintainability.
    <PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="5.0.0" />
    <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />

Egil.Orleans.StateMigration/Directory.Packages.props:20

  • The Microsoft.Extensions.DependencyInjection.Abstractions package version is inconsistent. This project uses version "10.0.3", while other projects use "9.0.3". For cross-project compatibility and consistency, consider aligning this version with the rest of the repository.
    <PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.3" />

Egil.Orleans.StateMigration/README.md:54

  • The guidance section recommends emitting logs/metrics when CLR-name fallback is used, but the implementation doesn't appear to include any logging infrastructure or instrumentation. Consider either:
  1. Implementing the logging/metrics mentioned in the documentation
  2. Updating the documentation to reflect that this is a recommendation for users to implement in their own code
  3. Providing extension points or events where users can hook in their own monitoring
Guidance:
- Aliases should be treated as immutable once data is persisted.
- Validate at startup:
  - duplicate aliases
  - unresolved `$type` mappings
- Emit logs/metrics when CLR-name fallback is used so systems can migrate toward aliases.

Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/Egil.Orleans.StateMigration.csproj:28

  • Package validation is disabled (EnablePackageValidation>false</EnablePackageValidation>). For a library intended for public release, consider enabling package validation to catch potential issues with package structure, compatibility, and breaking changes. This is especially important for libraries that will have multiple versions in production.
    <EnablePackageValidation>false</EnablePackageValidation>

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Egil.Orleans.StateMigration/Directory.Packages.props
Comment thread Egil.Orleans.StateMigration/Directory.Packages.props
Comment thread Egil.Orleans.StateMigration/Directory.Packages.props
Comment thread Egil.Orleans.StateMigration/README.md Outdated
Comment thread .github/workflows/egil-orleans-statemigration-ci.yml
@egil

egil commented Feb 25, 2026

Copy link
Copy Markdown
Owner Author

Addressed the review findings in this branch:

  • Fixed malformed-envelope fallback behavior in both converters (fail-fast instead of silently falling back to flattened parsing for invalid enveloped payloads).
    • Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/SystemTextJson/EnvelopedStorageJsonConverter.cs
    • Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/SystemTextJson/FlattenedStorageJsonConverter.cs
  • Fixed custom value property name handling so legacy/default envelope value property names are rejected consistently when custom names are configured.
    • Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/SystemTextJson/EnvelopedStorageJsonConverter.cs
    • Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/SystemTextJson/FlattenedStorageJsonConverter.cs
  • Replaced OnDeserialized(default!) with a non-null deserialization context surrogate and added callback tests asserting non-null context/service provider/runtime-client placeholders.
    • Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/SystemTextJson/DeserializationCallbackInvoker.cs
    • Egil.Orleans.StateMigration/test/Egil.Orleans.StateMigration.Tests/SystemTextJson/StorageJsonConverterOnDeserializedTests.cs
  • Added negative caching for unresolved type identities and cache invalidation on registration.
    • Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/StateTypeIdentity.cs
  • Expanded startup type-registration coverage to include static IMigrateFrom<,> mappings discovered from loaded assemblies.
    • Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/StateMigrationServiceCollectionExtensions.cs
  • Added dedicated tests for internal migration/type-identity behavior (reflection-driven tests).
    • Egil.Orleans.StateMigration/test/Egil.Orleans.StateMigration.Tests/StateMigrationInvokerTests.cs
    • Egil.Orleans.StateMigration/test/Egil.Orleans.StateMigration.Tests/StateTypeIdentityTests.cs
  • Added explicit GitHub Actions token permissions (contents: read) for workflow/jobs flagged by security scanning.
    • .github/workflows/egil-orleans-statemigration-ci.yml
  • Updated README wording to match current converter behavior regarding external migrators vs static migration path.
    • Egil.Orleans.StateMigration/README.md

Validation run:

  • dotnet build Egil.Orleans.StateMigration/Egil.Orleans.StateMigration.slnx -c Release
  • dotnet test Egil.Orleans.StateMigration/Egil.Orleans.StateMigration.slnx -c Release

Both pass locally.

@egil

egil commented Feb 25, 2026

Copy link
Copy Markdown
Owner Author

Implemented the IServiceProvider-based OnDeserialized context flow and pushed commit b3bf0f6.

Files updated:

  • Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/SystemTextJson/StorageJsonConverterFactory.cs
  • Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/SystemTextJson/StateMigrationJsonSerializerOptionsExtensions.cs
  • Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/SystemTextJson/EnvelopedStorageJsonConverter.cs
  • Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/SystemTextJson/FlattenedStorageJsonConverter.cs
  • Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/SystemTextJson/DeserializationCallbackInvoker.cs
  • Egil.Orleans.StateMigration/test/Egil.Orleans.StateMigration.Tests/SystemTextJson/StateMigrationJsonSerializerOptionsExtensionsTests.cs
  • Egil.Orleans.StateMigration/test/Egil.Orleans.StateMigration.Tests/SystemTextJson/StorageJsonConverterOnDeserializedTests.cs

What changed:

  • Converter factory now carries optional IServiceProvider into closed storage converters.
  • Added provider-aware AddStateMigrationSupport(...) overload handling and guardrails for conflicting provider reuse on the same JsonSerializerOptions instance.
  • Callback invocation now prefers Orleans OnDeserializedCallbacks when available and falls back to a non-null DeserializationContext that preserves the configured service provider.
  • Added tests for provider overload null/conflict behavior and callback invocation with configured provider.

Validation:

  • dotnet build Egil.Orleans.StateMigration/Egil.Orleans.StateMigration.slnx -c Release
  • dotnet test Egil.Orleans.StateMigration/Egil.Orleans.StateMigration.slnx -c Release
  • Passing: 69/69 tests.

@egil

egil commented Feb 25, 2026

Copy link
Copy Markdown
Owner Author

Follow-up workflow fix pushed in commit b934c00 for the failing validate-nuget check.

Root cause:

  • NuGet validation rule "Project url is not accessible" failed because PackageProjectUrl pointed to https://github.com/egil/framework/tree/main/Egil.Orleans.StateMigration, and that path does not exist on main until this PR merges.

Fix:

  • Updated Egil.Orleans.StateMigration/src/Egil.Orleans.StateMigration/Egil.Orleans.StateMigration.csproj to use stable project URL https://github.com/egil/framework so validation passes in PR builds as well as post-merge.

Local validation after the change:

  • dotnet build Egil.Orleans.StateMigration/Egil.Orleans.StateMigration.slnx -c Release
  • dotnet test Egil.Orleans.StateMigration/Egil.Orleans.StateMigration.slnx -c Release

@egil egil closed this Mar 29, 2026
@egil
egil deleted the feature/egil-orleans-statemigration-phase1 branch March 29, 2026 01:17
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.

3 participants