@cratis/pi 7.102.0 → 7.103.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package/corpus/harnesses/copilot/instructions/profiles.instructions.md +10 -1
- package/package/corpus/harnesses/copilot/instructions/pull-requests.instructions.md +2 -0
- package/package/corpus/harnesses/copilot/instructions/secrets.instructions.md +4 -0
- package/package/corpus/hooks/README.md +11 -1
- package/package/corpus/hooks/scripts/cratis-check-pr.mjs +12 -1
- package/package/corpus/hooks/scripts/cratis-guard-secrets.sh +79 -23
- package/package/corpus/hooks/scripts/cratis-guard-writes.sh +145 -40
- package/package/corpus/rules/profiles.md +10 -1
- package/package/corpus/rules/pull-requests.md +2 -0
- package/package/corpus/rules/secrets.md +4 -0
- package/package/corpus/skills/analyzing-dotnet-performance/LICENSE +23 -0
- package/package/corpus/skills/analyzing-dotnet-performance/NOTICE +36 -0
- package/package/corpus/skills/analyzing-dotnet-performance/SKILL.md +214 -0
- package/package/corpus/skills/analyzing-dotnet-performance/references/async-patterns.md +122 -0
- package/package/corpus/skills/analyzing-dotnet-performance/references/collections-and-linq.md +220 -0
- package/package/corpus/skills/analyzing-dotnet-performance/references/critical-patterns.md +291 -0
- package/package/corpus/skills/analyzing-dotnet-performance/references/io-and-serialization.md +135 -0
- package/package/corpus/skills/analyzing-dotnet-performance/references/memory-and-strings.md +219 -0
- package/package/corpus/skills/analyzing-dotnet-performance/references/regex-patterns.md +95 -0
- package/package/corpus/skills/analyzing-dotnet-performance/references/structural-patterns.md +38 -0
- package/package/corpus/skills/binlog-generation/LICENSE +23 -0
- package/package/corpus/skills/binlog-generation/NOTICE +22 -0
- package/package/corpus/skills/binlog-generation/SKILL.md +129 -0
- package/package/corpus/skills/check-bin-obj-clash/LICENSE +23 -0
- package/package/corpus/skills/check-bin-obj-clash/NOTICE +27 -0
- package/package/corpus/skills/check-bin-obj-clash/SKILL.md +127 -0
- package/package/corpus/skills/check-bin-obj-clash/references/common-causes-and-fixes.md +206 -0
- package/package/corpus/skills/coverage-analysis/LICENSE +23 -0
- package/package/corpus/skills/coverage-analysis/NOTICE +32 -0
- package/package/corpus/skills/coverage-analysis/SKILL.md +198 -0
- package/package/corpus/skills/coverage-analysis/references/guidelines.md +68 -0
- package/package/corpus/skills/coverage-analysis/references/output-format.md +91 -0
- package/package/corpus/skills/coverage-analysis/references/report-generation.md +58 -0
- package/package/corpus/skills/coverage-analysis/references/setup-discovery.md +307 -0
- package/package/corpus/skills/coverage-analysis/scripts/Compute-CrapScores.ps1 +80 -0
- package/package/corpus/skills/coverage-analysis/scripts/CoverageData.ps1 +272 -0
- package/package/corpus/skills/coverage-analysis/scripts/Extract-MethodCoverage.ps1 +65 -0
- package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +26 -1
- package/package/corpus/skills/cratis-screenplay-projections/SKILL.md +17 -0
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +17 -0
- package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +8 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +1 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/fast-path.md +7 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +1 -0
- package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +40 -0
- package/package/corpus/skills/cratis-screenplay-ui-composition/references/response-continuations.md +1 -0
- package/package/corpus/skills/cratis-screenplay-ui-composition/references/worked-flow.md +1 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +3 -2
- package/package/corpus/skills/csharp-refactoring/LICENSE +23 -0
- package/package/corpus/skills/csharp-refactoring/NOTICE +22 -0
- package/package/corpus/skills/csharp-refactoring/SKILL.md +175 -0
- package/package/corpus/skills/csharp-refactoring/references/operation-catalog.md +37 -0
- package/package/corpus/skills/directory-build-organization/LICENSE +23 -0
- package/package/corpus/skills/directory-build-organization/NOTICE +21 -0
- package/package/corpus/skills/directory-build-organization/SKILL.md +205 -0
- package/package/corpus/skills/directory-build-organization/references/common-patterns.md +56 -0
- package/package/corpus/skills/directory-build-organization/references/multi-level-examples.md +167 -0
- package/package/corpus/skills/directory-build-organization/references/targetframework-props-pitfall.md +54 -0
- package/package/corpus/skills/dotnet-aot-compat/LICENSE +23 -0
- package/package/corpus/skills/dotnet-aot-compat/NOTICE +18 -0
- package/package/corpus/skills/dotnet-aot-compat/SKILL.md +265 -0
- package/package/corpus/skills/dotnet-aot-compat/references/polyfills.md +43 -0
- package/package/corpus/skills/dotnet-trace-collect/LICENSE +23 -0
- package/package/corpus/skills/dotnet-trace-collect/NOTICE +65 -0
- package/package/corpus/skills/dotnet-trace-collect/SKILL.md +116 -0
- package/package/corpus/skills/dotnet-trace-collect/references/dotnet-monitor.md +97 -0
- package/package/corpus/skills/dotnet-trace-collect/references/dotnet-trace-collect-linux.md +84 -0
- package/package/corpus/skills/dotnet-trace-collect/references/dotnet-trace-collect.md +91 -0
- package/package/corpus/skills/dotnet-trace-collect/references/perfcollect.md +200 -0
- package/package/corpus/skills/dotnet-trace-collect/references/perfview.md +141 -0
- package/package/corpus/skills/dotnet-trace-collect/references/tool-selection.md +160 -0
- package/package/corpus/skills/dump-collect/LICENSE +23 -0
- package/package/corpus/skills/dump-collect/NOTICE +40 -0
- package/package/corpus/skills/dump-collect/SKILL.md +97 -0
- package/package/corpus/skills/dump-collect/references/container-dumps.md +412 -0
- package/package/corpus/skills/dump-collect/references/coreclr-dumps.md +108 -0
- package/package/corpus/skills/dump-collect/references/nativeaot-dumps.md +280 -0
- package/package/corpus/skills/eliminate-redundant-restores/LICENSE +23 -0
- package/package/corpus/skills/eliminate-redundant-restores/NOTICE +19 -0
- package/package/corpus/skills/eliminate-redundant-restores/SKILL.md +112 -0
- package/package/corpus/skills/extension-points/LICENSE +23 -0
- package/package/corpus/skills/extension-points/NOTICE +18 -0
- package/package/corpus/skills/extension-points/SKILL.md +248 -0
- package/package/corpus/skills/filter-syntax/LICENSE +23 -0
- package/package/corpus/skills/filter-syntax/NOTICE +17 -0
- package/package/corpus/skills/filter-syntax/SKILL.md +179 -0
- package/package/corpus/skills/including-generated-files/LICENSE +23 -0
- package/package/corpus/skills/including-generated-files/NOTICE +17 -0
- package/package/corpus/skills/including-generated-files/SKILL.md +139 -0
- package/package/corpus/skills/microbenchmarking/LICENSE +23 -0
- package/package/corpus/skills/microbenchmarking/NOTICE +36 -0
- package/package/corpus/skills/microbenchmarking/SKILL.md +131 -0
- package/package/corpus/skills/microbenchmarking/references/bdn-internals-and-tuning.md +143 -0
- package/package/corpus/skills/microbenchmarking/references/comparison-strategies.md +200 -0
- package/package/corpus/skills/microbenchmarking/references/diagnosers-and-exporters.md +150 -0
- package/package/corpus/skills/microbenchmarking/references/project-setup-and-running.md +189 -0
- package/package/corpus/skills/microbenchmarking/references/writing-benchmarks.md +310 -0
- package/package/corpus/skills/msbuild/LICENSE +23 -0
- package/package/corpus/skills/msbuild/NOTICE +55 -0
- package/package/corpus/skills/msbuild/SKILL.md +117 -0
- package/package/corpus/skills/msbuild/references/antipatterns/additional-antipatterns.md +291 -0
- package/package/corpus/skills/msbuild/references/antipatterns/incremental-build-inputs-outputs.md +57 -0
- package/package/corpus/skills/msbuild/references/antipatterns/private-assets.md +29 -0
- package/package/corpus/skills/msbuild/references/binlog-failure-analysis.md +85 -0
- package/package/corpus/skills/msbuild/references/binlog-generation.md +69 -0
- package/package/corpus/skills/msbuild/references/build-perf-baseline.md +493 -0
- package/package/corpus/skills/msbuild/references/build-perf-diagnostics.md +268 -0
- package/package/corpus/skills/msbuild/references/copy-to-output-directory.md +183 -0
- package/package/corpus/skills/msbuild/references/eval-performance.md +190 -0
- package/package/corpus/skills/msbuild/references/extension-points.md +281 -0
- package/package/corpus/skills/msbuild/references/incremental-build.md +365 -0
- package/package/corpus/skills/msbuild/references/msbuild-antipatterns.md +401 -0
- package/package/corpus/skills/orleans/LICENSE +21 -0
- package/package/corpus/skills/orleans/NOTICE +64 -0
- package/package/corpus/skills/orleans/SKILL.md +140 -0
- package/package/corpus/skills/orleans/references/anti-patterns.md +660 -0
- package/package/corpus/skills/orleans/references/configuration-api.md +933 -0
- package/package/corpus/skills/orleans/references/examples.md +66 -0
- package/package/corpus/skills/orleans/references/grain-api.md +784 -0
- package/package/corpus/skills/orleans/references/grains.md +75 -0
- package/package/corpus/skills/orleans/references/hosting.md +71 -0
- package/package/corpus/skills/orleans/references/implementation.md +591 -0
- package/package/corpus/skills/orleans/references/official-docs-index.md +250 -0
- package/package/corpus/skills/orleans/references/patterns.md +811 -0
- package/package/corpus/skills/orleans/references/persistence-api.md +495 -0
- package/package/corpus/skills/orleans/references/primitive-selection.md +35 -0
- package/package/corpus/skills/orleans/references/scheduling-and-services.md +295 -0
- package/package/corpus/skills/orleans/references/serialization-api.md +299 -0
- package/package/corpus/skills/orleans/references/streaming-api.md +396 -0
- package/package/corpus/skills/orleans/references/testing-patterns.md +210 -0
- package/package/corpus/skills/platform-detection/LICENSE +23 -0
- package/package/corpus/skills/platform-detection/NOTICE +17 -0
- package/package/corpus/skills/platform-detection/SKILL.md +230 -0
- package/package/corpus/skills/platform-detection/references/command-mode.md +27 -0
- package/package/corpus/skills/profiling/LICENSE +21 -0
- package/package/corpus/skills/profiling/NOTICE +50 -0
- package/package/corpus/skills/profiling/SKILL.md +144 -0
- package/package/corpus/skills/profiling/references/commands.md +439 -0
- package/package/corpus/skills/profiling/references/patterns.md +586 -0
- package/package/corpus/skills/profiling/references/profiling.md +190 -0
- package/package/corpus/skills/run-tests/LICENSE +23 -0
- package/package/corpus/skills/run-tests/NOTICE +19 -0
- package/package/corpus/skills/run-tests/SKILL.md +305 -0
- package/package/corpus/skills/target-authoring/LICENSE +23 -0
- package/package/corpus/skills/target-authoring/NOTICE +17 -0
- package/package/corpus/skills/target-authoring/SKILL.md +165 -0
- package/package/corpus/skills/vectorization/LICENSE +23 -0
- package/package/corpus/skills/vectorization/NOTICE +17 -0
- package/package/corpus/skills/vectorization/SKILL.md +189 -0
- package/package/profile-catalog.json +85 -1
- package/package.json +1 -1
|
@@ -0,0 +1,933 @@
|
|
|
1
|
+
# Configuration, Deployment, and Observability API
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- Silo Configuration
|
|
6
|
+
- Client Configuration
|
|
7
|
+
- .NET Aspire Integration
|
|
8
|
+
- Clustering Providers
|
|
9
|
+
- GC Configuration
|
|
10
|
+
- Observability
|
|
11
|
+
- Deployment Targets
|
|
12
|
+
- Heterogeneous Silos
|
|
13
|
+
- Silo Metadata (Orleans 9+)
|
|
14
|
+
- Silo Lifecycle
|
|
15
|
+
- Grain Directory
|
|
16
|
+
- TLS Configuration
|
|
17
|
+
- Dashboard (Orleans 10.0)
|
|
18
|
+
- Startup Tasks
|
|
19
|
+
- ADO.NET Configuration
|
|
20
|
+
- Azure App Service Deployment
|
|
21
|
+
- Kubernetes Deployment
|
|
22
|
+
- Handling Failures
|
|
23
|
+
- Cluster Management
|
|
24
|
+
- Messaging Delivery Guarantees
|
|
25
|
+
- Migration Guide (7.x → 10.x)
|
|
26
|
+
- Testing
|
|
27
|
+
- Best Practices Summary
|
|
28
|
+
- NuGet Packages Map
|
|
29
|
+
- Local Development Configuration
|
|
30
|
+
- Server Configuration
|
|
31
|
+
- Client Configuration
|
|
32
|
+
- Typical Configurations
|
|
33
|
+
- Service Fabric Deployment
|
|
34
|
+
- Consul Deployment
|
|
35
|
+
- Troubleshooting Deployments
|
|
36
|
+
- Observability Details
|
|
37
|
+
- Key Options Classes
|
|
38
|
+
|
|
39
|
+
Detailed configuration and operational patterns from official Orleans documentation.
|
|
40
|
+
|
|
41
|
+
## Silo Configuration
|
|
42
|
+
|
|
43
|
+
```csharp
|
|
44
|
+
var builder = Host.CreateApplicationBuilder(args);
|
|
45
|
+
|
|
46
|
+
builder.UseOrleans((context, silo) =>
|
|
47
|
+
{
|
|
48
|
+
if (context.HostingEnvironment.IsDevelopment())
|
|
49
|
+
{
|
|
50
|
+
silo.UseLocalhostClustering();
|
|
51
|
+
silo.AddMemoryGrainStorage("Default");
|
|
52
|
+
silo.UseInMemoryReminderService();
|
|
53
|
+
}
|
|
54
|
+
else
|
|
55
|
+
{
|
|
56
|
+
// Production clustering
|
|
57
|
+
silo.UseAzureStorageClustering(options =>
|
|
58
|
+
options.ConfigureTableServiceClient(
|
|
59
|
+
new DefaultAzureCredential(),
|
|
60
|
+
new Uri("https://mystorageaccount.table.core.windows.net")));
|
|
61
|
+
|
|
62
|
+
// Production persistence
|
|
63
|
+
silo.AddRedisGrainStorage("Default", options =>
|
|
64
|
+
options.ConfigurationOptions = ConfigurationOptions.Parse(redisConn));
|
|
65
|
+
|
|
66
|
+
// Production reminders
|
|
67
|
+
silo.UseRedisReminderService(options =>
|
|
68
|
+
options.ConfigurationOptions = ConfigurationOptions.Parse(redisConn));
|
|
69
|
+
|
|
70
|
+
silo.Configure<ClusterOptions>(options =>
|
|
71
|
+
{
|
|
72
|
+
options.ClusterId = "prod-cluster";
|
|
73
|
+
options.ServiceId = "my-service";
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Client Configuration
|
|
80
|
+
|
|
81
|
+
### Co-hosted Client (Recommended)
|
|
82
|
+
|
|
83
|
+
Client runs in same process as silo. Get `IClusterClient` from DI:
|
|
84
|
+
|
|
85
|
+
```csharp
|
|
86
|
+
var grain = serviceProvider.GetRequiredService<IClusterClient>()
|
|
87
|
+
.GetGrain<IMyGrain>("key");
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### External Client
|
|
91
|
+
|
|
92
|
+
```csharp
|
|
93
|
+
builder.UseOrleansClient(client =>
|
|
94
|
+
{
|
|
95
|
+
client.UseAzureStorageClustering(options =>
|
|
96
|
+
options.ConfigureTableServiceClient(connectionString));
|
|
97
|
+
|
|
98
|
+
client.Configure<ClusterOptions>(options =>
|
|
99
|
+
{
|
|
100
|
+
options.ClusterId = "prod-cluster";
|
|
101
|
+
options.ServiceId = "my-service";
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Connection Retry
|
|
107
|
+
|
|
108
|
+
```csharp
|
|
109
|
+
public class RetryFilter : IClientConnectionRetryFilter
|
|
110
|
+
{
|
|
111
|
+
private int _attempt;
|
|
112
|
+
public async Task<bool> ShouldRetryConnectionAttempt(
|
|
113
|
+
Exception exception, CancellationToken ct)
|
|
114
|
+
{
|
|
115
|
+
if (_attempt++ > 5) return false;
|
|
116
|
+
await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, _attempt)), ct);
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## .NET Aspire Integration
|
|
123
|
+
|
|
124
|
+
```csharp
|
|
125
|
+
// AppHost
|
|
126
|
+
var storage = builder.AddAzureStorage("storage");
|
|
127
|
+
var clustering = storage.AddTables("clustering");
|
|
128
|
+
var grainStorage = storage.AddBlobs("grain-state");
|
|
129
|
+
var redis = builder.AddRedis("redis");
|
|
130
|
+
|
|
131
|
+
var orleans = builder.AddOrleans("my-cluster")
|
|
132
|
+
.WithClustering(clustering)
|
|
133
|
+
.WithGrainStorage("Default", grainStorage)
|
|
134
|
+
.WithReminders(redis)
|
|
135
|
+
.WithMemoryStreams("StreamProvider");
|
|
136
|
+
|
|
137
|
+
builder.AddProject<Projects.Silo>("silo")
|
|
138
|
+
.WithReference(orleans);
|
|
139
|
+
|
|
140
|
+
builder.AddProject<Projects.WebFrontend>("web")
|
|
141
|
+
.WithReference(orleans.AsClient()); // client-only
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Clustering Providers
|
|
145
|
+
|
|
146
|
+
| Provider | Package | Use Case |
|
|
147
|
+
|---|---|---|
|
|
148
|
+
| Azure Table | `Microsoft.Orleans.Clustering.AzureStorage` | Azure-hosted |
|
|
149
|
+
| Redis | `Microsoft.Orleans.Clustering.Redis` | Redis-available environments |
|
|
150
|
+
| Cosmos DB | `Microsoft.Orleans.Clustering.Cosmos` | Cosmos-first architectures |
|
|
151
|
+
| ADO.NET | `Microsoft.Orleans.Clustering.AdoNet` | SQL Server / PostgreSQL |
|
|
152
|
+
| Consul | `Microsoft.Orleans.Clustering.Consul` | Consul-based infrastructure |
|
|
153
|
+
| Kubernetes | via sidecar | K8s native |
|
|
154
|
+
| Localhost | built-in | Dev only |
|
|
155
|
+
|
|
156
|
+
## GC Configuration
|
|
157
|
+
|
|
158
|
+
Critical for Orleans performance. Configure in project file:
|
|
159
|
+
|
|
160
|
+
```xml
|
|
161
|
+
<PropertyGroup>
|
|
162
|
+
<ServerGarbageCollection>true</ServerGarbageCollection>
|
|
163
|
+
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
|
|
164
|
+
</PropertyGroup>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Or via `runtimeconfig.json`:
|
|
168
|
+
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"runtimeOptions": {
|
|
172
|
+
"configProperties": {
|
|
173
|
+
"System.GC.Server": true,
|
|
174
|
+
"System.GC.Concurrent": true
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Observability
|
|
181
|
+
|
|
182
|
+
### Metrics (System.Diagnostics.Metrics)
|
|
183
|
+
|
|
184
|
+
Meter name: `"Microsoft.Orleans"`
|
|
185
|
+
|
|
186
|
+
```csharp
|
|
187
|
+
// OpenTelemetry export
|
|
188
|
+
builder.Services.AddOpenTelemetry()
|
|
189
|
+
.WithMetrics(metrics =>
|
|
190
|
+
{
|
|
191
|
+
metrics.AddMeter("Microsoft.Orleans");
|
|
192
|
+
metrics.AddOtlpExporter();
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Monitor from CLI:
|
|
197
|
+
```bash
|
|
198
|
+
dotnet counters monitor -n <Process> --counters Microsoft.Orleans
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Meter categories: Networking, Messaging, Gateway, Runtime, Catalog (activations), Directory, Consistent Ring, Watchdog, Client, Grains, App Requests, Reminders, Storage, Streams, Transactions.
|
|
202
|
+
|
|
203
|
+
### Distributed Tracing
|
|
204
|
+
|
|
205
|
+
```csharp
|
|
206
|
+
// Enable
|
|
207
|
+
siloBuilder.AddActivityPropagation();
|
|
208
|
+
clientBuilder.AddActivityPropagation();
|
|
209
|
+
|
|
210
|
+
// Or via options
|
|
211
|
+
services.Configure<ActivityPropagationGrainCallFilterOptions>(o =>
|
|
212
|
+
o.EnableDistributedTracing = true);
|
|
213
|
+
|
|
214
|
+
// Export
|
|
215
|
+
builder.Services.AddOpenTelemetry()
|
|
216
|
+
.WithTracing(tracing =>
|
|
217
|
+
{
|
|
218
|
+
tracing.AddSource("Microsoft.Orleans.Runtime");
|
|
219
|
+
tracing.AddSource("Microsoft.Orleans.Application");
|
|
220
|
+
tracing.AddOtlpExporter();
|
|
221
|
+
});
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Activity sources: `"Microsoft.Orleans.Runtime"`, `"Microsoft.Orleans.Application"`.
|
|
225
|
+
|
|
226
|
+
### Dashboard
|
|
227
|
+
|
|
228
|
+
```csharp
|
|
229
|
+
siloBuilder.UseDashboard(options =>
|
|
230
|
+
{
|
|
231
|
+
options.Port = 8080;
|
|
232
|
+
options.Host = "*";
|
|
233
|
+
});
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Secure with ASP.NET Core authorization middleware.
|
|
237
|
+
|
|
238
|
+
## Deployment Targets
|
|
239
|
+
|
|
240
|
+
### Azure Container Apps
|
|
241
|
+
|
|
242
|
+
```csharp
|
|
243
|
+
siloBuilder.UseAzureStorageClustering(options =>
|
|
244
|
+
options.ConfigureTableServiceClient(new DefaultAzureCredential(), tableUri));
|
|
245
|
+
|
|
246
|
+
// ACA provides automatic scaling, zero-downtime deployments
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Kubernetes
|
|
250
|
+
|
|
251
|
+
```csharp
|
|
252
|
+
siloBuilder.UseKubernetesHosting(); // auto-configures from K8s environment
|
|
253
|
+
|
|
254
|
+
// Requires proper RBAC, service account, and headless service
|
|
255
|
+
// Configure liveness and readiness probes
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Azure App Service
|
|
259
|
+
|
|
260
|
+
```csharp
|
|
261
|
+
// Use Azure Storage for clustering (no multicast)
|
|
262
|
+
// Configure sticky sessions for client gateway affinity
|
|
263
|
+
// Use deployment slots for zero-downtime upgrades
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Graceful Shutdown
|
|
267
|
+
|
|
268
|
+
```csharp
|
|
269
|
+
// Automatic with UseConsoleLifetime() or ASP.NET Core host
|
|
270
|
+
// Manual: await host.StopAsync(cancellationToken)
|
|
271
|
+
|
|
272
|
+
// Configure drain period
|
|
273
|
+
services.Configure<SiloMessagingOptions>(options =>
|
|
274
|
+
{
|
|
275
|
+
options.ShutdownGracePeriod = TimeSpan.FromSeconds(30);
|
|
276
|
+
});
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Heterogeneous Silos
|
|
280
|
+
|
|
281
|
+
Different silos can support different grain types. All must reference grain interfaces.
|
|
282
|
+
|
|
283
|
+
```csharp
|
|
284
|
+
services.Configure<GrainClassOptions>(options =>
|
|
285
|
+
{
|
|
286
|
+
options.ExcludedGrainTypes.Add("MyHeavyGrain");
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
services.Configure<TypeManagementOptions>(options =>
|
|
290
|
+
{
|
|
291
|
+
options.TypeMapRefreshInterval = TimeSpan.FromMinutes(1);
|
|
292
|
+
});
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Limitations: stateless grains and `[ImplicitStreamSubscription]` not supported in heterogeneous mode.
|
|
296
|
+
|
|
297
|
+
## Silo Metadata (Orleans 9+)
|
|
298
|
+
|
|
299
|
+
Label silos for placement filtering:
|
|
300
|
+
|
|
301
|
+
```csharp
|
|
302
|
+
siloBuilder.Configure<SiloMetadataOptions>(options =>
|
|
303
|
+
{
|
|
304
|
+
options.Metadata["zone"] = "us-east-1a";
|
|
305
|
+
options.Metadata["tier"] = "compute";
|
|
306
|
+
});
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Used with placement filtering for zone-aware and hardware-affinity placement.
|
|
310
|
+
|
|
311
|
+
## Silo Lifecycle
|
|
312
|
+
|
|
313
|
+
Ordered startup/shutdown via observable lifecycle. Components participate via `ILifecycleParticipant<ISiloLifecycle>`.
|
|
314
|
+
|
|
315
|
+
### Lifecycle Stages
|
|
316
|
+
|
|
317
|
+
| Stage | Value | Purpose |
|
|
318
|
+
|---|---|---|
|
|
319
|
+
| `First` | `int.MinValue` | Earliest stage |
|
|
320
|
+
| `RuntimeInitialize` | 2000 | Threading init |
|
|
321
|
+
| `RuntimeServices` | 4000 | Networking, agents |
|
|
322
|
+
| `RuntimeStorageServices` | 6000 | Storage init |
|
|
323
|
+
| `RuntimeGrainServices` | 8000 | Grain type management, membership, directory |
|
|
324
|
+
| `ApplicationServices` | 10000 | Application layer |
|
|
325
|
+
| `BecomeActive` | `Active - 1` | Join cluster |
|
|
326
|
+
| `Active` | 20000 | Ready for workload |
|
|
327
|
+
| `Last` | `int.MaxValue` | Latest stage |
|
|
328
|
+
|
|
329
|
+
## Grain Directory
|
|
330
|
+
|
|
331
|
+
Maps grain identity → activation location (silo). Ensures at most one activation.
|
|
332
|
+
|
|
333
|
+
| Implementation | Package | Notes |
|
|
334
|
+
|---|---|---|
|
|
335
|
+
| Distributed In-Cluster (default) | built-in | Eventually consistent DHT |
|
|
336
|
+
| Strongly-Consistent (Orleans 10 preview) | built-in | Versioned range locks, prevents duplicates |
|
|
337
|
+
| ADO.NET | `Microsoft.Orleans.GrainDirectory.AdoNet` | SQL Server, PostgreSQL, MySQL, Oracle |
|
|
338
|
+
| Azure Table | `Microsoft.Orleans.GrainDirectory.AzureStorage` | Azure-hosted |
|
|
339
|
+
| Redis | `Microsoft.Orleans.GrainDirectory.Redis` | Redis-available |
|
|
340
|
+
|
|
341
|
+
```csharp
|
|
342
|
+
// Per-grain-type directory
|
|
343
|
+
[GrainDirectory(GrainDirectoryName = "my-directory")]
|
|
344
|
+
public class MyGrain : Grain, IMyGrain { }
|
|
345
|
+
|
|
346
|
+
siloBuilder.AddRedisGrainDirectory("my-directory", options => { });
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## TLS Configuration
|
|
350
|
+
|
|
351
|
+
Package: `Microsoft.Orleans.Connections.Security`
|
|
352
|
+
|
|
353
|
+
```csharp
|
|
354
|
+
// Silo — certificate from file
|
|
355
|
+
var cert = X509CertificateLoader.LoadPkcs12FromFile("cert.pfx", "password");
|
|
356
|
+
siloBuilder.UseTls(cert, options =>
|
|
357
|
+
{
|
|
358
|
+
options.OnAuthenticateAsClient = (conn, ssl) =>
|
|
359
|
+
ssl.TargetHost = "my-service";
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
// Client
|
|
363
|
+
clientBuilder.UseTls(cert, options =>
|
|
364
|
+
options.AllowAnyRemoteCertificate()); // dev only
|
|
365
|
+
|
|
366
|
+
// Mutual TLS — client sends certificate for silo verification
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## Dashboard (Orleans 10.0)
|
|
370
|
+
|
|
371
|
+
Packages: `Microsoft.Orleans.Dashboard`, `Microsoft.Orleans.Dashboard.Abstractions`
|
|
372
|
+
|
|
373
|
+
```csharp
|
|
374
|
+
siloBuilder.AddDashboard();
|
|
375
|
+
app.MapOrleansDashboard(); // default /
|
|
376
|
+
app.MapOrleansDashboard(routePrefix: "/dashboard");
|
|
377
|
+
|
|
378
|
+
// Authorization
|
|
379
|
+
app.MapOrleansDashboard().RequireAuthorization("AdminPolicy");
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Features: cluster overview, grain monitoring, method profiling, reminder management, live log streaming, grain state inspection.
|
|
383
|
+
|
|
384
|
+
Options: `HideTrace` (bool), `CounterUpdateIntervalMs` (int, default 1000), `HistoryLength` (int, default 100).
|
|
385
|
+
|
|
386
|
+
Exclude grains from profiling: `[NoProfiling]` attribute.
|
|
387
|
+
|
|
388
|
+
## Startup Tasks
|
|
389
|
+
|
|
390
|
+
Preferred: use .NET `BackgroundService` or `IHostedService`. Register after `UseOrleans()`.
|
|
391
|
+
|
|
392
|
+
Remember that hosted services run once per host process. Scaling to multiple silos multiplies the loop. Use a well-known grain identity, broker consumer group, or external lease when the operation needs one logical cluster-wide owner.
|
|
393
|
+
|
|
394
|
+
```csharp
|
|
395
|
+
// BackgroundService approach
|
|
396
|
+
public class GrainInitializer : BackgroundService
|
|
397
|
+
{
|
|
398
|
+
private readonly IGrainFactory _grainFactory;
|
|
399
|
+
public GrainInitializer(IGrainFactory grainFactory) => _grainFactory = grainFactory;
|
|
400
|
+
protected override async Task ExecuteAsync(CancellationToken ct)
|
|
401
|
+
{
|
|
402
|
+
var grain = _grainFactory.GetGrain<IInitGrain>(0);
|
|
403
|
+
await grain.Initialize();
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Legacy startup task
|
|
408
|
+
siloBuilder.AddStartupTask(async (IServiceProvider sp, CancellationToken ct) =>
|
|
409
|
+
{
|
|
410
|
+
var grain = sp.GetRequiredService<IGrainFactory>().GetGrain<IInitGrain>(0);
|
|
411
|
+
await grain.Initialize();
|
|
412
|
+
});
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
Warning: exceptions from startup tasks stop the silo (fail-fast). Use them for deterministic lifecycle initialization/validation, not ordinary recurring work or transient remote calls. See [scheduling-and-services.md](scheduling-and-services.md) for the ownership decision.
|
|
416
|
+
|
|
417
|
+
## ADO.NET Configuration
|
|
418
|
+
|
|
419
|
+
NuGet packages: `Microsoft.Orleans.Clustering.AdoNet`, `Microsoft.Orleans.Persistence.AdoNet`, `Microsoft.Orleans.Reminders.AdoNet`
|
|
420
|
+
|
|
421
|
+
```csharp
|
|
422
|
+
siloBuilder.UseAdoNetClustering(options =>
|
|
423
|
+
{
|
|
424
|
+
options.Invariant = "Microsoft.Data.SqlClient"; // Orleans 10.0
|
|
425
|
+
options.ConnectionString = connectionString;
|
|
426
|
+
});
|
|
427
|
+
siloBuilder.AddAdoNetGrainStorage("Default", options =>
|
|
428
|
+
{
|
|
429
|
+
options.Invariant = "Microsoft.Data.SqlClient";
|
|
430
|
+
options.ConnectionString = connectionString;
|
|
431
|
+
});
|
|
432
|
+
siloBuilder.UseAdoNetReminderService(options =>
|
|
433
|
+
{
|
|
434
|
+
options.Invariant = "Microsoft.Data.SqlClient";
|
|
435
|
+
options.ConnectionString = connectionString;
|
|
436
|
+
});
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
Supported databases and invariants:
|
|
440
|
+
|
|
441
|
+
| Database | Invariant |
|
|
442
|
+
|---|---|
|
|
443
|
+
| SQL Server | `Microsoft.Data.SqlClient` (10.0) / `System.Data.SqlClient` (7-9) |
|
|
444
|
+
| PostgreSQL | `Npgsql` |
|
|
445
|
+
| MySQL/MariaDB | `MySql.Data.MySqlClient` |
|
|
446
|
+
| Oracle | `Oracle.DataAccess.Client` |
|
|
447
|
+
|
|
448
|
+
**Prerequisite**: run SQL setup scripts from `dotnet/orleans` repo before use.
|
|
449
|
+
|
|
450
|
+
## Azure App Service Deployment
|
|
451
|
+
|
|
452
|
+
Requires VNet integration and private ports for silo-to-silo communication.
|
|
453
|
+
|
|
454
|
+
```csharp
|
|
455
|
+
var endpointAddress = IPAddress.Parse(builder.Configuration["WEBSITE_PRIVATE_IP"]!);
|
|
456
|
+
var strPorts = builder.Configuration["WEBSITE_PRIVATE_PORTS"]!.Split(',');
|
|
457
|
+
var (siloPort, gatewayPort) = (int.Parse(strPorts[0]), int.Parse(strPorts[1]));
|
|
458
|
+
siloBuilder.ConfigureEndpoints(endpointAddress, siloPort, gatewayPort,
|
|
459
|
+
listenOnAnyHostAddress: true);
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
Enable private ports: `az webapp config set --generic-configurations '{"vnetPrivatePortsCount": "2"}'`
|
|
463
|
+
|
|
464
|
+
## Kubernetes Deployment
|
|
465
|
+
|
|
466
|
+
Package: `Microsoft.Orleans.Hosting.Kubernetes`
|
|
467
|
+
|
|
468
|
+
```csharp
|
|
469
|
+
siloBuilder.UseKubernetesHosting();
|
|
470
|
+
// Auto-configures SiloName, AdvertisedIPAddress, endpoints from K8s env
|
|
471
|
+
// Still need separate clustering provider (Redis, Azure Table, etc.)
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
Required pod labels: `orleans/serviceId`, `orleans/clusterId`. Required env: `POD_NAME`, `POD_NAMESPACE`, `POD_IP`.
|
|
475
|
+
|
|
476
|
+
Key YAML: `terminationGracePeriodSeconds: 180`, `DOTNET_SHUTDOWNTIMEOUTSECONDS: "120"`, `maxUnavailable: 0`, `maxSurge: 1`, `minReadySeconds: 60`.
|
|
477
|
+
|
|
478
|
+
RBAC: `get`, `watch`, `list`, `delete`, `patch` on `pods`.
|
|
479
|
+
|
|
480
|
+
## Handling Failures
|
|
481
|
+
|
|
482
|
+
- Method calls return exceptions; Orleans propagates across silos
|
|
483
|
+
- Getting a grain reference always succeeds locally (lazy activation)
|
|
484
|
+
- Orleans auto-reactivates failed grains on next call on another silo
|
|
485
|
+
- At-most-once message delivery by default (no automatic retries)
|
|
486
|
+
|
|
487
|
+
Recovery strategies:
|
|
488
|
+
1. **Retry** — suitable when no half-done state changes
|
|
489
|
+
2. **Reload state** — `ReadStateAsync()` to refresh from storage
|
|
490
|
+
3. **Transactions** — for multi-grain atomicity
|
|
491
|
+
4. **Process Manager / Saga** — for complex multi-grain orchestration
|
|
492
|
+
|
|
493
|
+
## Cluster Management
|
|
494
|
+
|
|
495
|
+
Fully distributed peer-to-peer membership protocol.
|
|
496
|
+
|
|
497
|
+
```csharp
|
|
498
|
+
siloBuilder.Configure<ClusterMembershipOptions>(options =>
|
|
499
|
+
{
|
|
500
|
+
options.NumProbedSilos = 10; // default (Orleans 9+)
|
|
501
|
+
options.NumVotesForDeathDeclaration = 2;
|
|
502
|
+
options.DeathVoteExpirationTimeout = TimeSpan.FromSeconds(180);
|
|
503
|
+
options.ProbeTimeout = TimeSpan.FromSeconds(10);
|
|
504
|
+
options.NumMissedProbesLimit = 3;
|
|
505
|
+
});
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
Typical failure detection: ~15 seconds (Orleans 9+). Properties: handles any number of failures, self-monitoring with health scoring, indirect probing, table unavailability never causes false death declarations.
|
|
509
|
+
|
|
510
|
+
## Messaging Delivery Guarantees
|
|
511
|
+
|
|
512
|
+
Default: **at-most-once** (no automatic retries). Message delivered once or not at all, never twice.
|
|
513
|
+
|
|
514
|
+
With retries: **at-least-once** (may arrive multiple times, no dedup). Every message has automatic configurable timeout.
|
|
515
|
+
|
|
516
|
+
## Migration Guide (7.x → 10.x)
|
|
517
|
+
|
|
518
|
+
| Change | Migration |
|
|
519
|
+
|---|---|
|
|
520
|
+
| `AddGrainCallFilter` removed | Use `AddIncomingGrainCallFilter` |
|
|
521
|
+
| `RegisterTimer` obsoleted | Use `RegisterGrainTimer` with `GrainTimerCreationOptions` |
|
|
522
|
+
| ADO.NET invariant | Use `Microsoft.Data.SqlClient` instead of `System.Data.SqlClient` |
|
|
523
|
+
| `CancelRequestOnTimeout` default → `false` | Set `true` explicitly if needed |
|
|
524
|
+
| Default placement → `ResourceOptimized` (9.2) | Explicitly set if different behavior needed |
|
|
525
|
+
|
|
526
|
+
**Rolling upgrades 7.x → 10.0 NOT recommended** due to protocol changes. Deploy new cluster, migrate state, switch traffic.
|
|
527
|
+
|
|
528
|
+
## Testing
|
|
529
|
+
|
|
530
|
+
### InProcessTestCluster (Orleans 9+, recommended)
|
|
531
|
+
|
|
532
|
+
```csharp
|
|
533
|
+
var builder = new InProcessTestClusterBuilder();
|
|
534
|
+
builder.ConfigureSilo((options, siloBuilder) =>
|
|
535
|
+
{
|
|
536
|
+
siloBuilder.AddMemoryGrainStorage("Default");
|
|
537
|
+
});
|
|
538
|
+
var cluster = builder.Build();
|
|
539
|
+
await cluster.DeployAsync();
|
|
540
|
+
|
|
541
|
+
var grain = cluster.Client.GetGrain<IMyGrain>(0);
|
|
542
|
+
var result = await grain.DoWork();
|
|
543
|
+
|
|
544
|
+
// Dynamic silo management
|
|
545
|
+
var newSilo = await cluster.StartSiloAsync();
|
|
546
|
+
await cluster.StopSiloAsync(newSilo);
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### TestCluster (legacy, still supported)
|
|
550
|
+
|
|
551
|
+
```csharp
|
|
552
|
+
var builder = new TestClusterBuilder();
|
|
553
|
+
builder.AddSiloBuilderConfigurator<TestSiloConfig>();
|
|
554
|
+
var cluster = builder.Build();
|
|
555
|
+
cluster.Deploy();
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
### xUnit Sharing
|
|
559
|
+
|
|
560
|
+
```csharp
|
|
561
|
+
[CollectionDefinition("Orleans")]
|
|
562
|
+
public class ClusterCollection : ICollectionFixture<ClusterFixture> { }
|
|
563
|
+
|
|
564
|
+
[Collection("Orleans")]
|
|
565
|
+
public class MyTests
|
|
566
|
+
{
|
|
567
|
+
private readonly TestCluster _cluster;
|
|
568
|
+
public MyTests(ClusterFixture fixture) => _cluster = fixture.Cluster;
|
|
569
|
+
}
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
## Best Practices Summary
|
|
573
|
+
|
|
574
|
+
**Good fit**: millions of loosely coupled entities, small single-threaded, interactive workloads.
|
|
575
|
+
|
|
576
|
+
**Bad fit**: shared memory between entities, few large multithreaded entities, global coordination, long-running batch jobs.
|
|
577
|
+
|
|
578
|
+
**Rules**:
|
|
579
|
+
- Avoid chatty inter-grain communication
|
|
580
|
+
- Avoid bottleneck grains — use staged aggregation
|
|
581
|
+
- Never block threads
|
|
582
|
+
- Use `[StatelessWorker]` for stateless operations
|
|
583
|
+
- Initial `ReadStateAsync` happens automatically before `OnActivateAsync`
|
|
584
|
+
- Call `WriteStateAsync()` after state changes
|
|
585
|
+
- Retry only idempotent operations with an explicit end-to-end policy; retries can produce duplicate delivery
|
|
586
|
+
|
|
587
|
+
## NuGet Packages Map
|
|
588
|
+
|
|
589
|
+
### Core
|
|
590
|
+
|
|
591
|
+
| Package | Purpose |
|
|
592
|
+
|---|---|
|
|
593
|
+
| `Microsoft.Orleans.Server` | Silo hosting (includes Client) |
|
|
594
|
+
| `Microsoft.Orleans.Client` | Standalone client |
|
|
595
|
+
| `Microsoft.Orleans.Sdk` | Grain development metapackage |
|
|
596
|
+
|
|
597
|
+
### Dashboard
|
|
598
|
+
|
|
599
|
+
| Package | Purpose |
|
|
600
|
+
|---|---|
|
|
601
|
+
| `Microsoft.Orleans.Dashboard` | Built-in dashboard (10.0) |
|
|
602
|
+
| `Microsoft.Orleans.Dashboard.Abstractions` | Dashboard abstractions |
|
|
603
|
+
|
|
604
|
+
### Clustering
|
|
605
|
+
|
|
606
|
+
| Package | Backend |
|
|
607
|
+
|---|---|
|
|
608
|
+
| `Microsoft.Orleans.Clustering.AzureStorage` | Azure Table |
|
|
609
|
+
| `Microsoft.Orleans.Clustering.AdoNet` | SQL Server, PostgreSQL, MySQL, Oracle |
|
|
610
|
+
| `Microsoft.Orleans.Clustering.Redis` | Redis |
|
|
611
|
+
| `Microsoft.Orleans.Clustering.Cosmos` | Cosmos DB |
|
|
612
|
+
| `Microsoft.Orleans.Clustering.Consul` | Consul |
|
|
613
|
+
|
|
614
|
+
### Persistence
|
|
615
|
+
|
|
616
|
+
| Package | Backend |
|
|
617
|
+
|---|---|
|
|
618
|
+
| `Microsoft.Orleans.Persistence.AzureStorage` | Azure Table/Blob |
|
|
619
|
+
| `Microsoft.Orleans.Persistence.AdoNet` | SQL |
|
|
620
|
+
| `Microsoft.Orleans.Persistence.Redis` | Redis |
|
|
621
|
+
| `Microsoft.Orleans.Persistence.Cosmos` | Cosmos DB |
|
|
622
|
+
| `Microsoft.Orleans.Persistence.DynamoDB` | DynamoDB |
|
|
623
|
+
|
|
624
|
+
### Reminders
|
|
625
|
+
|
|
626
|
+
| Package | Backend |
|
|
627
|
+
|---|---|
|
|
628
|
+
| `Microsoft.Orleans.Reminders.AzureStorage` | Azure Table |
|
|
629
|
+
| `Microsoft.Orleans.Reminders.AdoNet` | SQL |
|
|
630
|
+
| `Microsoft.Orleans.Reminders.Redis` | Redis |
|
|
631
|
+
| `Microsoft.Orleans.Reminders.Cosmos` | Cosmos DB |
|
|
632
|
+
|
|
633
|
+
### Durable Jobs (Experimental)
|
|
634
|
+
|
|
635
|
+
| Package | Purpose |
|
|
636
|
+
|---|---|
|
|
637
|
+
| `Microsoft.Orleans.DurableJobs` | One-time persistent future delivery to target grains |
|
|
638
|
+
| `Microsoft.Orleans.DurableJobs.AzureStorage` | Azure Blob-backed job journal/shards |
|
|
639
|
+
|
|
640
|
+
The Orleans 10.3.1 packages are `10.3.1-alpha.1`. Pin them to the same release line as the rest of Orleans and review [scheduling-and-services.md](scheduling-and-services.md) before adoption.
|
|
641
|
+
|
|
642
|
+
### Journaling (Experimental)
|
|
643
|
+
|
|
644
|
+
| Package | Purpose |
|
|
645
|
+
|---|---|
|
|
646
|
+
| `Microsoft.Orleans.Journaling` | Operation-journaled durable collections, values, and state |
|
|
647
|
+
| `Microsoft.Orleans.Journaling.AzureStorage` | Azure Blob journal provider |
|
|
648
|
+
|
|
649
|
+
The Orleans 10.3.1 packages are `10.3.1-alpha.1`. This surface is separate from `Microsoft.Orleans.EventSourcing` and `JournaledGrain`.
|
|
650
|
+
|
|
651
|
+
### Grain Directory
|
|
652
|
+
|
|
653
|
+
| Package | Backend |
|
|
654
|
+
|---|---|
|
|
655
|
+
| `Microsoft.Orleans.GrainDirectory.AzureStorage` | Azure Table |
|
|
656
|
+
| `Microsoft.Orleans.GrainDirectory.AdoNet` | SQL |
|
|
657
|
+
| `Microsoft.Orleans.GrainDirectory.Redis` | Redis |
|
|
658
|
+
|
|
659
|
+
### Streaming
|
|
660
|
+
|
|
661
|
+
| Package | Backend |
|
|
662
|
+
|---|---|
|
|
663
|
+
| `Microsoft.Orleans.Streaming.EventHubs` | Azure Event Hubs |
|
|
664
|
+
| `Microsoft.Orleans.Streaming.AzureStorage` | Azure Queue |
|
|
665
|
+
|
|
666
|
+
### Serializers
|
|
667
|
+
|
|
668
|
+
| Package | Format |
|
|
669
|
+
|---|---|
|
|
670
|
+
| `Microsoft.Orleans.Serialization.SystemTextJson` | System.Text.Json |
|
|
671
|
+
| `Microsoft.Orleans.Serialization.NewtonsoftJson` | Newtonsoft.Json |
|
|
672
|
+
| `Microsoft.Orleans.Serialization.MessagePack` | MessagePack |
|
|
673
|
+
| `Microsoft.Orleans.Serialization.Protobuf` | Protobuf |
|
|
674
|
+
|
|
675
|
+
### Other
|
|
676
|
+
|
|
677
|
+
| Package | Purpose |
|
|
678
|
+
|---|---|
|
|
679
|
+
| `Microsoft.Orleans.Transactions` | ACID transactions |
|
|
680
|
+
| `Microsoft.Orleans.EventSourcing` | JournaledGrain |
|
|
681
|
+
| `Microsoft.Orleans.Connections.Security` | TLS |
|
|
682
|
+
| `Microsoft.Orleans.Hosting.Kubernetes` | K8s hosting |
|
|
683
|
+
| `Microsoft.Orleans.Analyzers` | Code analyzers |
|
|
684
|
+
| `Microsoft.Orleans.TestingHost` | TestCluster |
|
|
685
|
+
|
|
686
|
+
## Local Development Configuration
|
|
687
|
+
|
|
688
|
+
```csharp
|
|
689
|
+
// Silo — single-node, in-memory everything
|
|
690
|
+
await Host.CreateDefaultBuilder(args)
|
|
691
|
+
.UseOrleans(silo => silo.UseLocalhostClustering())
|
|
692
|
+
.RunConsoleAsync();
|
|
693
|
+
|
|
694
|
+
// Client — connect to local cluster
|
|
695
|
+
using IHost host = Host.CreateDefaultBuilder(args)
|
|
696
|
+
.UseOrleansClient(client => client.UseLocalhostClustering())
|
|
697
|
+
.UseConsoleLifetime()
|
|
698
|
+
.Build();
|
|
699
|
+
await host.StartAsync();
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
Packages: `Microsoft.Orleans.Server` for silo, `Microsoft.Orleans.Client` for client.
|
|
703
|
+
|
|
704
|
+
## Server Configuration
|
|
705
|
+
|
|
706
|
+
```csharp
|
|
707
|
+
builder.UseOrleans((context, silo) =>
|
|
708
|
+
{
|
|
709
|
+
silo.Configure<ClusterOptions>(options =>
|
|
710
|
+
{
|
|
711
|
+
options.ClusterId = "my-cluster";
|
|
712
|
+
options.ServiceId = "my-service";
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
silo.Configure<EndpointOptions>(options =>
|
|
716
|
+
{
|
|
717
|
+
options.SiloPort = 11111;
|
|
718
|
+
options.GatewayPort = 30000;
|
|
719
|
+
options.AdvertisedIPAddress = IPAddress.Loopback;
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
// Clustering, persistence, reminders, streams...
|
|
723
|
+
});
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
## Client Configuration
|
|
727
|
+
|
|
728
|
+
```csharp
|
|
729
|
+
builder.UseOrleansClient(client =>
|
|
730
|
+
{
|
|
731
|
+
client.Configure<ClusterOptions>(options =>
|
|
732
|
+
{
|
|
733
|
+
options.ClusterId = "my-cluster";
|
|
734
|
+
options.ServiceId = "my-service";
|
|
735
|
+
});
|
|
736
|
+
// Clustering provider must match silo
|
|
737
|
+
client.UseAzureStorageClustering(options =>
|
|
738
|
+
options.ConfigureTableServiceClient(connectionString));
|
|
739
|
+
});
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
Prefer `TokenCredential` with `DefaultAzureCredential` over connection strings for Azure providers.
|
|
743
|
+
|
|
744
|
+
## Typical Configurations
|
|
745
|
+
|
|
746
|
+
### Aspire + Redis (Recommended for Orleans 8+)
|
|
747
|
+
|
|
748
|
+
```csharp
|
|
749
|
+
// AppHost
|
|
750
|
+
var redis = builder.AddRedis("redis");
|
|
751
|
+
var orleans = builder.AddOrleans("cluster")
|
|
752
|
+
.WithClustering(redis)
|
|
753
|
+
.WithGrainStorage("Default", redis)
|
|
754
|
+
.WithReminders(redis);
|
|
755
|
+
|
|
756
|
+
// Silo
|
|
757
|
+
builder.AddKeyedRedisClient("redis");
|
|
758
|
+
builder.UseOrleans();
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
### Azure Storage Production
|
|
762
|
+
|
|
763
|
+
```csharp
|
|
764
|
+
silo.UseAzureStorageClustering(options =>
|
|
765
|
+
options.ConfigureTableServiceClient(
|
|
766
|
+
new DefaultAzureCredential(),
|
|
767
|
+
new Uri("https://account.table.core.windows.net")));
|
|
768
|
+
silo.AddAzureBlobGrainStorage("Default", options =>
|
|
769
|
+
options.ConfigureBlobServiceClient(
|
|
770
|
+
new DefaultAzureCredential(),
|
|
771
|
+
new Uri("https://account.blob.core.windows.net")));
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
### SQL Server Production
|
|
775
|
+
|
|
776
|
+
```csharp
|
|
777
|
+
silo.UseAdoNetClustering(options =>
|
|
778
|
+
{
|
|
779
|
+
options.Invariant = "Microsoft.Data.SqlClient"; // Orleans 10.0
|
|
780
|
+
options.ConnectionString = connectionString;
|
|
781
|
+
});
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
### Unreliable Test Cluster (No External Deps)
|
|
785
|
+
|
|
786
|
+
```csharp
|
|
787
|
+
// Silo
|
|
788
|
+
silo.UseDevelopmentClustering(primarySiloEndpoint);
|
|
789
|
+
|
|
790
|
+
// Client
|
|
791
|
+
client.UseStaticClustering(gateways);
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
## Service Fabric Deployment
|
|
795
|
+
|
|
796
|
+
Orleans integrates with Azure Service Fabric for deployment, service discovery, and failover.
|
|
797
|
+
|
|
798
|
+
```csharp
|
|
799
|
+
// Use Service Fabric's membership system
|
|
800
|
+
siloBuilder.UseServiceFabricClustering(serviceContext);
|
|
801
|
+
```
|
|
802
|
+
|
|
803
|
+
Key considerations:
|
|
804
|
+
- Service Fabric manages silo lifecycle through reliable services
|
|
805
|
+
- Use Service Fabric's naming service for cluster membership
|
|
806
|
+
- Co-locate silos with Service Fabric partitions for locality
|
|
807
|
+
- Configure endpoints through Service Fabric service manifests
|
|
808
|
+
|
|
809
|
+
## Consul Deployment
|
|
810
|
+
|
|
811
|
+
Package: `Microsoft.Orleans.Clustering.Consul`
|
|
812
|
+
|
|
813
|
+
```csharp
|
|
814
|
+
// Silo
|
|
815
|
+
silo.UseConsulSiloClustering(options =>
|
|
816
|
+
options.ConfigureConsulClient(new Uri("http://localhost:8500")));
|
|
817
|
+
|
|
818
|
+
// Client
|
|
819
|
+
client.UseConsulClientClustering(options =>
|
|
820
|
+
options.ConfigureConsulClient(new Uri("http://localhost:8500")));
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
Uses Consul Key/Value store with Check-And-Set (CAS) operations. Keys prefixed with `orleans/`. Each silo registers silo details + last alive timestamp.
|
|
824
|
+
|
|
825
|
+
Limitations: only basic membership protocol (no atomic multi-key updates), KV not replicated between Consul data centers.
|
|
826
|
+
|
|
827
|
+
## Troubleshooting Deployments
|
|
828
|
+
|
|
829
|
+
### Common `SiloUnavailableException` Causes
|
|
830
|
+
|
|
831
|
+
- Silo crashed/terminated and evicted from cluster
|
|
832
|
+
- Network partition between silos
|
|
833
|
+
- Silo shutting down during request
|
|
834
|
+
- No silos available for client connection
|
|
835
|
+
|
|
836
|
+
### Configuration Issues
|
|
837
|
+
|
|
838
|
+
- Mismatched clustering provider between silos and clients
|
|
839
|
+
- Local/dev config used in cloud environments
|
|
840
|
+
- Missing/incorrect connection strings
|
|
841
|
+
- `ClusterId` / `ServiceId` mismatch between silo and client
|
|
842
|
+
|
|
843
|
+
### Container/K8s Issues
|
|
844
|
+
|
|
845
|
+
- Insufficient resource requests/limits
|
|
846
|
+
- Clustering provider connectivity failure
|
|
847
|
+
- SiloPort (11111) / GatewayPort (30000) not correctly exposed
|
|
848
|
+
- Missing liveness/readiness probes
|
|
849
|
+
|
|
850
|
+
### Debugging
|
|
851
|
+
|
|
852
|
+
```csharp
|
|
853
|
+
builder.Logging.SetMinimumLevel(LogLevel.Information);
|
|
854
|
+
// For Orleans internals:
|
|
855
|
+
builder.Logging.AddFilter("Orleans", LogLevel.Debug);
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
## Observability Details
|
|
859
|
+
|
|
860
|
+
### Silo Error Code Monitoring
|
|
861
|
+
|
|
862
|
+
Orleans silos emit structured error codes with categories:
|
|
863
|
+
- `Runtime` — activation, deactivation, messaging errors
|
|
864
|
+
- `Catalog` — grain directory, activation catalog
|
|
865
|
+
- `Networking` — connection, socket errors
|
|
866
|
+
- `Membership` — cluster membership, failure detection
|
|
867
|
+
- `Storage` — persistence provider errors
|
|
868
|
+
|
|
869
|
+
Monitor via standard `Microsoft.Extensions.Logging` — error codes appear in log messages.
|
|
870
|
+
|
|
871
|
+
### Client Error Code Monitoring
|
|
872
|
+
|
|
873
|
+
Client-side error categories:
|
|
874
|
+
- `Gateway` — connection to silo gateways
|
|
875
|
+
- `Messaging` — request/response failures, timeouts
|
|
876
|
+
- `Runtime` — client lifecycle errors
|
|
877
|
+
|
|
878
|
+
### OpenTelemetry Full Setup
|
|
879
|
+
|
|
880
|
+
```csharp
|
|
881
|
+
builder.Services.AddOpenTelemetry()
|
|
882
|
+
.WithMetrics(metrics =>
|
|
883
|
+
{
|
|
884
|
+
metrics.AddMeter("Microsoft.Orleans");
|
|
885
|
+
metrics.AddOtlpExporter();
|
|
886
|
+
})
|
|
887
|
+
.WithTracing(tracing =>
|
|
888
|
+
{
|
|
889
|
+
tracing.AddSource("Microsoft.Orleans.Runtime");
|
|
890
|
+
tracing.AddSource("Microsoft.Orleans.Application");
|
|
891
|
+
tracing.AddOtlpExporter();
|
|
892
|
+
});
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
### Metrics Categories
|
|
896
|
+
|
|
897
|
+
| Category | What It Tracks |
|
|
898
|
+
|---|---|
|
|
899
|
+
| Networking | Connections, bytes sent/received |
|
|
900
|
+
| Messaging | Messages sent/received, queue lengths |
|
|
901
|
+
| Gateway | Client connections, active gateways |
|
|
902
|
+
| Runtime | Thread pool, memory, CPU |
|
|
903
|
+
| Catalog | Activations, activation creation/destruction |
|
|
904
|
+
| Directory | Directory lookups, registrations |
|
|
905
|
+
| Grains | Per-grain-type activation counts |
|
|
906
|
+
| App Requests | Grain method call latency and throughput |
|
|
907
|
+
| Reminders | Active reminders, ticks |
|
|
908
|
+
| Storage | Read/write latency, failures |
|
|
909
|
+
| Streams | Events processed, subscription counts |
|
|
910
|
+
| Transactions | Commit/abort rates |
|
|
911
|
+
|
|
912
|
+
## Key Options Classes
|
|
913
|
+
|
|
914
|
+
| Class | Purpose |
|
|
915
|
+
|---|---|
|
|
916
|
+
| `ClusterOptions` | ClusterId, ServiceId |
|
|
917
|
+
| `ClusterMembershipOptions` | Probing, death votes, failure detection |
|
|
918
|
+
| `SiloMessagingOptions` | ResponseTimeout, ShutdownGracePeriod |
|
|
919
|
+
| `ClientMessagingOptions` | ResponseTimeout, CancelRequestOnTimeout |
|
|
920
|
+
| `GrainCollectionOptions` | CollectionAge, memory shedding |
|
|
921
|
+
| `GrainClassOptions` | ExcludedGrainTypes |
|
|
922
|
+
| `GrainVersioningOptions` | Compatibility and version selector strategies |
|
|
923
|
+
| `TypeManagementOptions` | TypeMapRefreshInterval |
|
|
924
|
+
| `SiloMetadataOptions` | Metadata labels for placement filtering |
|
|
925
|
+
| `ResourceOptimizedPlacementOptions` | Placement weights (CPU, memory, etc.) |
|
|
926
|
+
| `EndpointOptions` | Silo/gateway ports |
|
|
927
|
+
| `LoadSheddingOptions` | CPU threshold for load shedding |
|
|
928
|
+
| `SchedulingOptions` | Scheduler behavior |
|
|
929
|
+
| `NetworkingOptions` | Socket/connection timeouts |
|
|
930
|
+
| `StatisticsOptions` | Statistics output |
|
|
931
|
+
| `ActivityPropagationGrainCallFilterOptions` | Distributed tracing |
|
|
932
|
+
| `DashboardOptions` | Dashboard port, trace hiding, update interval |
|
|
933
|
+
| `GrainProfilerOptions` | Profiling behavior |
|