Skip to content

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.

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.

Every versioned request carries the numeric interface version used by its caller. Orleans:

  1. Reads the versions supported by silos for that grain interface.
  2. Applies a compatibility strategy to determine which activation versions can process the requested version.
  3. Applies a selector strategy when a new activation needs placement.
  4. 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.

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.

  • 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.