Grain interface versioning
Grain interface versioning lets silos with different interface versions coexist during a deployment. It is a numeric routing and placement policy. It doesn’t version persistent state, validate the structural compatibility of two .NET interfaces, or migrate data.
Assign a version
Section titled “Assign a version”Apply VersionAttribute to a grain interface:
[Version(2)]public interface ICartGrain : IGrainWithStringKey{ Task<Cart> GetAsync(); Task AddAsync(Item item);}The value is an unsigned 16-bit integer. Interfaces without the attribute have version 0. Use monotonically increasing values for successive contract revisions.
How routing works
Section titled “How routing works”Every versioned request carries the numeric interface version used by its caller. Orleans:
- Reads the versions supported by silos for that grain interface.
- Applies a compatibility strategy to determine which activation versions can process the requested version.
- Applies a selector strategy when a new activation needs placement.
- Routes the request to a silo supporting one of the selected versions.
If a request reaches an existing activation whose version is incompatible, Orleans deactivates it with reason IncompatibleRequest, invalidates the stale address, and retries placement for a compatible activation.
Configure cluster defaults
Section titled “Configure cluster defaults”GrainVersioningOptions defaults to BackwardCompatible and AllCompatibleVersions:
var builder = Host.CreateApplicationBuilder();
builder.UseOrleans(siloBuilder =>{ siloBuilder.Configure<GrainVersioningOptions>(options => { options.DefaultCompatibilityStrategy = nameof(BackwardCompatible); options.DefaultVersionSelectorStrategy = nameof(AllCompatibleVersions); });});The configured strategy names resolve registered Orleans strategy services. Configure every silo consistently before a heterogeneous deployment.
Orleans also exposes runtime strategy changes through IVersionManager, implemented by the management grain. Changes can apply cluster-wide or to a specific GrainInterfaceType. Runtime overrides are operational state: coordinate them carefully and reset them to configured defaults after the deployment.
Scope and limitations
Section titled “Scope and limitations”- Stateless worker grains aren’t versioned.
- Streaming interfaces aren’t versioned.
- State and storage schema evolution are separate responsibilities.
- Version routing only helps while all deployed implementations honor the declared compatibility contract.
See deploying new grain versions for a rolling-upgrade sequence.
