-
Notifications
You must be signed in to change notification settings - Fork 153
Use Orleans with .NET Aspire #840
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
0e9c33b
Merge pull request #866 from dotnet/main
github-actions[bot] 33e3f01
Add Aspire + Orleans docs
ReubenBond 5bf3927
Update orleans.md
IEvangelist 870a553
Update docs/fundamentals/orleans.md
ReubenBond 1782b07
Update docs/fundamentals/orleans.md
ReubenBond 7e5d6ef
Update docs/fundamentals/orleans.md
ReubenBond 1621c99
Update docs/fundamentals/orleans.md
ReubenBond 9ea1369
Update docs/fundamentals/orleans.md
ReubenBond 81d2886
Update docs/fundamentals/orleans.md
ReubenBond e7a0092
Update docs/fundamentals/orleans.md
ReubenBond d871590
Update docs/fundamentals/orleans.md
ReubenBond 5b3909b
Update docs/fundamentals/orleans.md
ReubenBond d8ae052
Update docs/fundamentals/orleans.md
ReubenBond 084aa3d
Update docs/fundamentals/orleans.md
ReubenBond 8bd9e39
Update docs/fundamentals/orleans.md
ReubenBond 5a21d0c
Update docs/fundamentals/orleans.md
ReubenBond 5a342bf
Use code snippets. Overhaul
ReubenBond 4562cb7
Try to fix highlighting
ReubenBond 7ed761f
Use capitalization on folder name to make the linter be quiet
ReubenBond 2d3c4d6
Fix linter warnings
ReubenBond 7e06ac6
Update docs/frameworks/orleans.md
IEvangelist 6c10075
Update docs/frameworks/orleans.md
IEvangelist File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
--- | ||
title: Use Orleans with .NET Aspire | ||
description: Learn how to use Orleans with .NET Aspire | ||
ms.date: 05/3/2024 | ||
ms.topic: overview | ||
--- | ||
|
||
# Use Orleans with .NET Aspire | ||
|
||
Orleans and .NET Aspire are built for each other. .NET Aspire's application model lets you describe the services, databases, and other resources/infrastructure in your app and how they relate. Orleans' provides a straightforward way to build distributed applications which are elastically scalable and fault-tolerant. .NET Aspire is used to configure and orchestrate Orleans and its dependencies, such as, by providing Orleans with database cluster membership and storage. | ||
|
||
Orleans is represented as a resource in .NET Aspire. The Orleans resource includes configuration which your service needs to operate, such as cluster membership providers and storage providers. | ||
|
||
## Prerequisites | ||
|
||
- .NET 8.0 SDK or later | ||
- .NET Aspire workload | ||
- Orleans version 8.1.0 or later | ||
|
||
For more information, see [.NET Aspire setup and tooling](../fundamentals/setup-tooling.md). | ||
IEvangelist marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Get started | ||
|
||
To get started you need to add the Orleans hosting package to your app host project by installing the [Aspire.Hosting.Orleans](https://www.nuget.org/packages/Aspire.Hosting.Orleans) NuGet package. | ||
|
||
### [.NET CLI](#tab/dotnet-cli) | ||
|
||
```dotnetcli | ||
dotnet add package Aspire.Hosting.Orleans --prerelease | ||
``` | ||
|
||
### [PackageReference](#tab/package-reference) | ||
|
||
```xml | ||
<PackageReference Include="Aspire.Hosting.Orleans" | ||
Version="[SelectVersion]" /> | ||
``` | ||
|
||
--- | ||
|
||
For more information, see [dotnet add package](/dotnet/core/tools/dotnet-add-package) or [Manage package dependencies in .NET applications](/dotnet/core/tools/dependencies). | ||
|
||
The Orleans resource is added to the .NET Aspire distributed application builder using the `AddOrleans(string name)` method, which returns an Orleans resource builder. | ||
The name provided to the Orleans resource is for diagnostic purposes. For most applications, a value of `"default"` will suffice. | ||
|
||
:::code language="csharp" source="snippets/Orleans/OrleansAppHost/Program.cs" range="12"::: | ||
|
||
The Orleans resource builder offers methods to configure your Orleans resource. In the following example, the Orleans resource is configured with clustering and grain storage using the `WithClustering` and `WithGrainStorage` methods respectively: | ||
|
||
:::code language="csharp" source="snippets/Orleans/OrleansAppHost/Program.cs" range="3-14" highlight="4-5,11-12"::: | ||
|
||
This tells Orleans that any service referencing it will also need to reference the `clusteringTable` resource. | ||
|
||
To participate in an Orleans cluster, reference the Orleans resource from your service project, either using `WithReference(orleans)` to participate as an Orleans server, or `WithReference(orleans.AsClient())` to participate as a client. When you reference the Orleans resource from your service, those resources will also be referenced: | ||
|
||
:::code language="csharp" source="snippets/Orleans/OrleansAppHost/Program.cs" range="16-22"::: | ||
|
||
Putting that all together, here is an example of an Aspire AppHost project which includes: | ||
|
||
- An Orleans resource with clustering and storage. | ||
- An Orleans server project, 'OrleansServer'. | ||
- An Orleans client project, 'OrleansClient'. | ||
|
||
:::code language="csharp" source="snippets/Orleans/OrleansAppHost/Program.cs" ::: | ||
|
||
To consume the .NET Aspire Orleans resource from an Orleans server project, there are a few steps: | ||
|
||
1. Add the relevant .NET Aspire components. In this example, you're using _Aspire.Azure.Data.Tables_ and _Aspire.Azure.Storage.Blobs_. | ||
2. Add the Orleans provider packages for those .NET Aspire components. In this example, you're using _Microsoft.Orleans.Persistence.AzureStorage_ and _Microsoft.Orleans.Clustering.AzureStorage_. | ||
3. Add Orleans to the host application builder. | ||
|
||
In the _Program.cs_ file of your Orleans server project, you must configure the .NET Aspire components you are using and add Orleans to the host builder. Note that the names provided must match the names used in the .NET Aspire app host project: "clustering" for the clustering provider, and "grain-state" for the grain state storage provider: | ||
|
||
:::code language="csharp" source="snippets/Orleans/OrleansServer/Program.cs" ::: | ||
|
||
You do similarly in the _OrleansClient_ project, adding the .NET Aspire resources which your project needs to join the Orleans cluster as a client, and configuring the host builder to add an Orleans client: | ||
|
||
:::code language="csharp" source="snippets/Orleans/OrleansClient/Program.cs" ::: | ||
|
||
## Enabling OpenTelemetry | ||
|
||
By convention, .NET Aspire application include a project for defining default configuration and behavior for your service. This project is called the _service default_ project and templates create it with a name ending in _ServiceDefaults_. | ||
To configure Orleans for OpenTelemetry in .NET Aspire, you will need to apply configuration to your service defaults project following the [Orleans observability](/dotnet/orleans/host/monitoring/) guide. | ||
In short, you will need to modify the `ConfigureOpenTelemetry` method to add the Orleans _meters_ and _tracing_ instruments. The following code snippet shows the _Extensions.cs_ file from a service defaults project which has been modified to include metrics and traces from Orleans. | ||
|
||
:::code language="csharp" source="snippets/Orleans/OrleansServiceDefaults/Extensions.cs" range="40-68" highlight="15,19-20"::: | ||
|
||
## Supported providers | ||
|
||
The Orleans Aspire integration supports a limited subset of Orleans providers today: | ||
|
||
- Clustering: | ||
- Redis | ||
- Azure Storage Tables | ||
- Persistence: | ||
- Redis | ||
- Azure Storage Tables | ||
- Azure Storage Blobs | ||
- Reminders: | ||
- Redis | ||
- Azure Storage Tables | ||
- Grain directory: | ||
- Redis | ||
- Azure Storage Tables | ||
|
||
Streaming providers are not supported as of Orleans version 8.1.0. |
15 changes: 7 additions & 8 deletions
15
...lr/SignalR.AppHost/SignalR.AppHost.csproj → ...eans/OrleansAppHost/OrleansAppHost.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,22 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<IsAspireHost>true</IsAspireHost> | ||
<UserSecretsId>28af853d-fd6a-45a4-9e12-2e51806fe248</UserSecretsId> | ||
<UserSecretsId>88427062-d086-46c2-b35e-171d742a6fe0</UserSecretsId> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\SignalR.ApiService\SignalR.ApiService.csproj" /> | ||
<ProjectReference Include="..\SignalR.Web\SignalR.Web.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.0.0-preview.7.24251.11" /> | ||
<PackageReference Include="Aspire.Hosting.Orleans" Version="8.0.0-preview.7.24251.11" /> | ||
<PackageReference Include="Aspire.Hosting.Azure" Version="8.0.0-preview.7.24251.11" /> | ||
<PackageReference Include="Aspire.Hosting.Azure.SignalR" Version="8.0.0-preview.7.24251.11" /> | ||
<PackageReference Include="Aspire.Hosting.Azure.Storage" Version="8.0.0-preview.7.24251.11" /> | ||
|
||
<ProjectReference Include="..\OrleansServer\OrleansServer.csproj" /> | ||
<ProjectReference Include="..\OrleansClient\OrleansClient.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
33 changes: 33 additions & 0 deletions
33
docs/frameworks/snippets/Orleans/OrleansAppHost/Program.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
var builder = DistributedApplication.CreateBuilder(args); | ||
|
||
// Add the resources which you will use for Orleans clustering and | ||
// grain state storage. | ||
var storage = builder.AddAzureStorage("storage").RunAsEmulator(); | ||
var clusteringTable = storage.AddTables("clustering"); | ||
var grainStorage = storage.AddBlobs("grain-state"); | ||
|
||
// Add the Orleans resource to the Aspire DistributedApplication | ||
// builder, then configure it with Azure Table Storage for clustering | ||
// and Azure Blob Storage for grain storage. | ||
var orleans = builder.AddOrleans("default") | ||
.WithClustering(clusteringTable) | ||
.WithGrainStorage("Default", grainStorage); | ||
|
||
// Add our server project and reference your 'orleans' resource from it. | ||
// it can join the Orleans cluster as a service. | ||
// This implicitly add references to the required resources. | ||
// In this case, that is the 'clusteringTable' resource declared earlier. | ||
builder.AddProject<Projects.OrleansServer>("silo") | ||
.WithReference(orleans) | ||
.WithReplicas(3); | ||
|
||
// Reference the Orleans resource as a client from the 'frontend' | ||
// project so that it can connect to the Orleans cluster. | ||
builder.AddProject<Projects.OrleansClient>("frontend") | ||
.WithReference(orleans.AsClient()) | ||
.WithExternalHttpEndpoints() | ||
.WithReplicas(3); | ||
|
||
// Build and run the application. | ||
using var app = builder.Build(); | ||
await app.RunAsync(); |
44 changes: 44 additions & 0 deletions
44
docs/frameworks/snippets/Orleans/OrleansAppHost/Properties/launchSettings.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
{ | ||
"profiles": { | ||
"https": { | ||
"commandName": "Project", | ||
"launchBrowser": true, | ||
"dotnetRunMessages": true, | ||
"applicationUrl": "https://localhost:15887;http://localhost:15888", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development", | ||
"DOTNET_ENVIRONMENT": "Development", | ||
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16031", | ||
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", | ||
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" | ||
} | ||
}, | ||
"http": { | ||
"commandName": "Project", | ||
"launchBrowser": true, | ||
"dotnetRunMessages": true, | ||
"applicationUrl": "http://localhost:15888", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development", | ||
"DOTNET_ENVIRONMENT": "Development", | ||
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031", | ||
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", | ||
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", | ||
"ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" | ||
} | ||
}, | ||
"generate-manifest": { | ||
"commandName": "Project", | ||
"launchBrowser": true, | ||
"dotnetRunMessages": true, | ||
"commandLineArgs": "--publisher manifest --output-path aspire-manifest.json", | ||
"applicationUrl": "http://localhost:15888", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development", | ||
"DOTNET_ENVIRONMENT": "Development", | ||
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031" | ||
} | ||
} | ||
}, | ||
"$schema": "http://json.schemastore.org/launchsettings.json" | ||
} |
File renamed without changes.
65 changes: 65 additions & 0 deletions
65
docs/frameworks/snippets/Orleans/OrleansAppHost/aspire-manifest.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
{ | ||
"resources": { | ||
"storage": { | ||
"type": "azure.bicep.v0", | ||
"path": "storage.module.bicep", | ||
"params": { | ||
"principalId": "", | ||
"principalType": "" | ||
} | ||
}, | ||
"clustering": { | ||
"type": "value.v0", | ||
"connectionString": "{storage.outputs.tableEndpoint}" | ||
}, | ||
"grainstate": { | ||
"type": "value.v0", | ||
"connectionString": "{storage.outputs.blobEndpoint}" | ||
}, | ||
"silo": { | ||
"type": "project.v0", | ||
"path": "../OrleansServer/OrleansServer.csproj", | ||
"env": { | ||
"OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true", | ||
"OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true", | ||
"ASPNETCORE_FORWARDEDHEADERS_ENABLED": "true", | ||
"Orleans__Clustering__ProviderType": "AzureTableStorage", | ||
"Orleans__Clustering__ServiceKey": "clustering", | ||
"ConnectionStrings__clustering": "{clustering.connectionString}", | ||
"Orleans__GrainStorage__Default__ProviderType": "AzureBlobStorage", | ||
"Orleans__GrainStorage__Default__ServiceKey": "grainstate", | ||
"ConnectionStrings__grainstate": "{grainstate.connectionString}", | ||
"Orleans__ClusterId": "c7673f46dfc745c8b4492b957aa42408", | ||
"Orleans__Endpoints__SiloPort": "{silo.bindings.orleans-silo.targetPort}", | ||
"Orleans__Endpoints__GatewayPort": "{silo.bindings.orleans-gateway.targetPort}", | ||
"Orleans__EnableDistributedTracing": "true" | ||
}, | ||
"bindings": { | ||
"http": { | ||
"scheme": "http", | ||
"protocol": "tcp", | ||
"transport": "http", | ||
"external": true | ||
}, | ||
"https": { | ||
"scheme": "https", | ||
"protocol": "tcp", | ||
"transport": "http", | ||
"external": true | ||
}, | ||
"orleans-silo": { | ||
"scheme": "tcp", | ||
"protocol": "tcp", | ||
"transport": "tcp", | ||
"targetPort": 8000 | ||
}, | ||
"orleans-gateway": { | ||
"scheme": "tcp", | ||
"protocol": "tcp", | ||
"transport": "tcp", | ||
"targetPort": 8001 | ||
} | ||
} | ||
} | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
docs/frameworks/snippets/Orleans/OrleansAppHost/storage.module.bicep
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
targetScope = 'resourceGroup' | ||
|
||
@description('') | ||
param location string = resourceGroup().location | ||
|
||
@description('') | ||
param principalId string | ||
|
||
@description('') | ||
param principalType string | ||
|
||
|
||
resource storageAccount_1XR3Um8QY 'Microsoft.Storage/storageAccounts@2022-09-01' = { | ||
name: toLower(take('storage${uniqueString(resourceGroup().id)}', 24)) | ||
location: location | ||
tags: { | ||
'aspire-resource-name': 'storage' | ||
} | ||
sku: { | ||
name: 'Standard_GRS' | ||
} | ||
kind: 'StorageV2' | ||
properties: { | ||
accessTier: 'Hot' | ||
networkAcls: { | ||
defaultAction: 'Allow' | ||
} | ||
} | ||
} | ||
|
||
resource blobService_vTLU20GRg 'Microsoft.Storage/storageAccounts/blobServices@2022-09-01' = { | ||
parent: storageAccount_1XR3Um8QY | ||
name: 'default' | ||
properties: { | ||
} | ||
} | ||
|
||
resource roleAssignment_Gz09cEnxb 'Microsoft.Authorization/roleAssignments@2022-04-01' = { | ||
scope: storageAccount_1XR3Um8QY | ||
name: guid(storageAccount_1XR3Um8QY.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')) | ||
properties: { | ||
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe') | ||
principalId: principalId | ||
principalType: principalType | ||
} | ||
} | ||
|
||
resource roleAssignment_HRj6MDafS 'Microsoft.Authorization/roleAssignments@2022-04-01' = { | ||
scope: storageAccount_1XR3Um8QY | ||
name: guid(storageAccount_1XR3Um8QY.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')) | ||
properties: { | ||
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3') | ||
principalId: principalId | ||
principalType: principalType | ||
} | ||
} | ||
|
||
resource roleAssignment_r0wA6OpKE 'Microsoft.Authorization/roleAssignments@2022-04-01' = { | ||
scope: storageAccount_1XR3Um8QY | ||
name: guid(storageAccount_1XR3Um8QY.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88')) | ||
properties: { | ||
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88') | ||
principalId: principalId | ||
principalType: principalType | ||
} | ||
} | ||
|
||
output blobEndpoint string = storageAccount_1XR3Um8QY.properties.primaryEndpoints.blob | ||
output queueEndpoint string = storageAccount_1XR3Um8QY.properties.primaryEndpoints.queue | ||
output tableEndpoint string = storageAccount_1XR3Um8QY.properties.primaryEndpoints.table |
21 changes: 21 additions & 0 deletions
21
docs/frameworks/snippets/Orleans/OrleansClient/OrleansClient.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Aspire.Azure.Data.Tables" Version="8.0.0-preview.7.24251.11" /> | ||
<PackageReference Include="Microsoft.Orleans.Client" Version="8.1.0" /> | ||
<PackageReference Include="Microsoft.Orleans.Clustering.AzureStorage" Version="8.1.0" /> | ||
<ProjectReference Include="..\OrleansContracts\OrleansContracts.csproj" /> | ||
<ProjectReference Include="..\OrleansServiceDefaults\OrleansServiceDefaults.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.