RuntimeReplicationConfig source
This page is part of the documentation for Orleans.Lattice 9.9.0 (release line 9.9), built 2026-10-04. It is also published as markdown, with every table and list, at source.md, and llms.txt lists every page.The source of the RuntimeReplicationConfig sample.
Program.cs
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Orleans.Hosting;
using Orleans.Lattice;
using Orleans.Lattice.Api.Replication;
using Orleans.Lattice.Replication;
// Runtime per-tree replication configuration sample.
//
// This sample hosts a single-silo Orleans cluster and drives replication
// enablement at RUNTIME through the control facade instead of the static
// LatticeReplicationOptions.ReplicatedTrees options map. The facade writes to the replicated
// sys-replication-config CRDT system tree; every cluster that enrolls that
// tree converges on the same per-tree enabled/mode decision.
//
// The flow is scripted and non-interactive: it enables a tree, reports the
// live config, demonstrates that an in-place mode change is rejected, then
// disables the tree and exits. There is no auth stack registered, so the
// default allow-all access gate authorizes every facade call; a production
// deployment would register Orleans.Lattice.Auth and author through the
// fail-closed API access gate.
const string TreeName = "orders";
using var host = Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.None);
})
.UseOrleans(silo =>
{
silo.UseLocalhostClustering(serviceId: "runtime-replication-config-sample", clusterId: "site-a");
silo.AddMemoryGrainStorageAsDefault();
silo.UseInMemoryReminderService();
silo.AddLattice((services, name) => services.AddMemoryGrainStorage(name));
// Enable the replication engine for this cluster. No peers are declared:
// this single-silo sample exercises the local authoring and reporting
// path, not cross-cluster shipping. ClusterId stamps this cluster's
// origin and satisfies the runtime preconditions for enablement.
// enableRuntimeConfig: true enrols the sys-replication-config tree so
// runtime enablement decisions are themselves a replicated CRDT - the one
// static enrolment the runtime-config model requires; every other tree is
// enabled dynamically through the facade below.
silo.AddLatticeReplication(
opts =>
{
opts.ClusterId = "site-a";
},
enableRuntimeConfig: true);
// Register the runtime replication control API. This binds
// ILatticeReplicationControl over the config authority.
silo.AddLatticeReplicationApi();
})
.Build();
Console.Write("Silo starting...");
await host.StartAsync();
Console.WriteLine(" ready.");
Console.WriteLine();
var control = host.Services.GetRequiredService<ILatticeReplicationControl>();
// 1. Enable replication for the "orders" tree under an OrSet merge mode. The
// mode is fixed at enable-time and cannot be changed in place afterwards.
Console.WriteLine($"Enabling replication for tree '{TreeName}' under {LatticeMergeMode.OrSet}...");
var enabled = await control.EnableReplicationAsync(TreeName, LatticeMergeMode.OrSet);
Console.WriteLine(
$" enabled: tree={enabled.TreeId} mode={enabled.Mode} " +
$"alreadyEnabled={enabled.AlreadyEnabled} bootstrapRequested={enabled.BootstrapRequested}");
Console.WriteLine();
// 2. Report the live per-tree configuration as converged in the config tree.
await PrintConfigAsync(control);
// 3. An in-place mode change is rejected by design. The sanctioned path to
// change a tree's merge mode is disable-then-re-enable, which re-bootstraps.
Console.WriteLine($"Attempting an in-place mode change to {LatticeMergeMode.LwwRegister} (expected to be rejected)...");
try
{
await control.EnableReplicationAsync(TreeName, LatticeMergeMode.LwwRegister);
Console.WriteLine(" unexpected: the mode change was NOT rejected.");
}
catch (LatticeReplicationModeChangeRejectedException ex)
{
Console.WriteLine($" rejected as expected: {ex.Message}");
}
Console.WriteLine();
// 4. Disable replication for the tree. This removes the tree's resolved runtime
// mode (its fixed merge mode is kept) and never purges data already
// replicated to peers. It does not tear down a shipper that is already
// running: one that keeps shipping has its entries dropped (and the batch
// acknowledged) by peers that resolve no mode.
Console.WriteLine($"Disabling replication for tree '{TreeName}'...");
var disabled = await control.DisableReplicationAsync(TreeName);
Console.WriteLine($" disabled: tree={disabled.TreeId} alreadyDisabled={disabled.AlreadyDisabled}");
Console.WriteLine();
// 5. Report the config again to show the tree is now disabled.
await PrintConfigAsync(control);
Console.WriteLine("Sample complete. Stopping silo...");
await host.StopAsync();
Console.WriteLine("Done.");
static async Task PrintConfigAsync(ILatticeReplicationControl control)
{
var report = await control.GetReplicationConfigAsync();
Console.WriteLine($"Replication config ({report.Trees.Count} tree(s)):");
foreach (var tree in report.Trees)
{
var mode = tree.Mode?.ToString() ?? "(none)";
Console.WriteLine(
$" tree={tree.TreeId} enabled={tree.Enabled} mode={mode} ambiguous={tree.Ambiguous}");
}
Console.WriteLine();
}
RuntimeReplicationConfig.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<RootNamespace>Orleans.Lattice.Samples.RuntimeReplicationConfig</RootNamespace>
<AssemblyName>Orleans.Lattice.Samples.RuntimeReplicationConfig</AssemblyName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.11" />
<PackageReference Include="Microsoft.Orleans.Server" Version="10.2.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\lattice\Orleans.Lattice.csproj" />
<ProjectReference Include="..\..\src\lattice.replication\Orleans.Lattice.Replication.csproj" />
<ProjectReference Include="..\..\src\lattice.api.replication\Orleans.Lattice.Api.Replication.csproj" />
</ItemGroup>
</Project>