From 8812ba7888f683ac4f4567f7ca02b4b09a60e586 Mon Sep 17 00:00:00 2001 From: Egil Hansen <egil@assimilated.dk> Date: Tue, 21 Jan 2025 20:30:42 +0000 Subject: [PATCH] Upgrade chat room orleans sample to dotnet 9 (#7014) * Upgrade ChatRoom orleans sample to dotnet 9 * Set default name to Anonymous if not specified * Remove unused using * Ensure chatroom message history doesn't grow above 100 * Update orleans/ChatRoom/ChatRoom.Service/ChannelGrain.cs --------- Co-authored-by: David Pine <david.pine@microsoft.com> --- .../ChatRoom.Client/ChatRoom.Client.csproj | 13 ++++---- orleans/ChatRoom/ChatRoom.Client/Program.cs | 4 +-- orleans/ChatRoom/ChatRoom.Common/ChatMsg.cs | 6 ++-- .../ChatRoom.Common/ChatRoom.Common.csproj | 7 ++-- .../ChatRoom/ChatRoom.Common/IChannelGrain.cs | 4 +-- .../ChatRoom/ChatRoom.Service/ChannelGrain.cs | 32 +++++++++++-------- .../ChatRoom.Service/ChatRoom.Service.csproj | 6 ++-- orleans/ChatRoom/ChatRoom.Service/Program.cs | 10 +++--- orleans/ChatRoom/ChatRoom.slnLaunch | 15 +++++++++ orleans/ChatRoom/README.md | 2 +- 10 files changed, 60 insertions(+), 39 deletions(-) create mode 100644 orleans/ChatRoom/ChatRoom.slnLaunch diff --git a/orleans/ChatRoom/ChatRoom.Client/ChatRoom.Client.csproj b/orleans/ChatRoom/ChatRoom.Client/ChatRoom.Client.csproj index 37c9e76de9b..78e8b4af9c6 100644 --- a/orleans/ChatRoom/ChatRoom.Client/ChatRoom.Client.csproj +++ b/orleans/ChatRoom/ChatRoom.Client/ChatRoom.Client.csproj @@ -1,12 +1,11 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0</TargetFramework> + <TargetFramework>net9.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <OutputType>Exe</OutputType> - <ServerGarbageCollection>true</ServerGarbageCollection> - </PropertyGroup> + </PropertyGroup> <ItemGroup> <None Remove="logo.png" /> @@ -17,8 +16,10 @@ </ItemGroup> <ItemGroup> - <PackageReference Include="Spectre.Console" Version="0.48.0" /> - <PackageReference Include="Spectre.Console.ImageSharp" Version="0.48.0" /> + <PackageReference Include="Microsoft.Orleans.Client" Version="9.0.1" /> + <PackageReference Include="SixLabors.ImageSharp" Version="3.1.6" /> + <PackageReference Include="Spectre.Console" Version="0.49.1" /> + <PackageReference Include="Spectre.Console.ImageSharp" Version="0.49.1" /> </ItemGroup> <ItemGroup> diff --git a/orleans/ChatRoom/ChatRoom.Client/Program.cs b/orleans/ChatRoom/ChatRoom.Client/Program.cs index 382525dbf10..b6c39d8b5bc 100644 --- a/orleans/ChatRoom/ChatRoom.Client/Program.cs +++ b/orleans/ChatRoom/ChatRoom.Client/Program.cs @@ -2,13 +2,13 @@ using ChatRoom; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Orleans.Runtime; using Spectre.Console; using var host = new HostBuilder() .UseOrleansClient(clientBuilder => { - clientBuilder.UseLocalhostClustering() + clientBuilder + .UseLocalhostClustering() .AddMemoryStreams("chat"); }) .Build(); diff --git a/orleans/ChatRoom/ChatRoom.Common/ChatMsg.cs b/orleans/ChatRoom/ChatRoom.Common/ChatMsg.cs index fabb9b09376..a064b9a04dd 100644 --- a/orleans/ChatRoom/ChatRoom.Common/ChatMsg.cs +++ b/orleans/ChatRoom/ChatRoom.Common/ChatMsg.cs @@ -1,12 +1,12 @@ -namespace ChatRoom; +namespace ChatRoom; -[GenerateSerializer] +[GenerateSerializer, Immutable] public record class ChatMsg( string? Author, string Text) { [Id(0)] - public string Author { get; init; } = Author ?? "Alexey"; + public string Author { get; init; } = Author ?? "Anonymous"; [Id(1)] public DateTimeOffset Created { get; init; } = DateTimeOffset.Now; diff --git a/orleans/ChatRoom/ChatRoom.Common/ChatRoom.Common.csproj b/orleans/ChatRoom/ChatRoom.Common/ChatRoom.Common.csproj index b6cb0913e0c..67398f6cd68 100644 --- a/orleans/ChatRoom/ChatRoom.Common/ChatRoom.Common.csproj +++ b/orleans/ChatRoom/ChatRoom.Common/ChatRoom.Common.csproj @@ -1,14 +1,15 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0</TargetFramework> + <TargetFramework>net9.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> + <RootNamespace>ChatRoomt</RootNamespace> </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.Orleans.Sdk" Version="8.0.0" /> - <PackageReference Include="Microsoft.Orleans.Streaming" Version="8.0.0" /> + <PackageReference Include="Microsoft.Orleans.Sdk" Version="9.0.1" /> + <PackageReference Include="Microsoft.Orleans.Streaming" Version="9.0.1" /> </ItemGroup> </Project> \ No newline at end of file diff --git a/orleans/ChatRoom/ChatRoom.Common/IChannelGrain.cs b/orleans/ChatRoom/ChatRoom.Common/IChannelGrain.cs index 52505de0038..de7e35d33cf 100644 --- a/orleans/ChatRoom/ChatRoom.Common/IChannelGrain.cs +++ b/orleans/ChatRoom/ChatRoom.Common/IChannelGrain.cs @@ -1,6 +1,4 @@ -using Orleans.Runtime; - -namespace ChatRoom; +namespace ChatRoom; public interface IChannelGrain : IGrainWithStringKey { diff --git a/orleans/ChatRoom/ChatRoom.Service/ChannelGrain.cs b/orleans/ChatRoom/ChatRoom.Service/ChannelGrain.cs index 10250b7679f..35811b23e89 100644 --- a/orleans/ChatRoom/ChatRoom.Service/ChannelGrain.cs +++ b/orleans/ChatRoom/ChatRoom.Service/ChannelGrain.cs @@ -1,24 +1,23 @@ -using Orleans.Runtime; -using Orleans.Streams; +using Orleans.Streams; namespace ChatRoom; -public class ChannelGrain : Grain, IChannelGrain +public sealed class ChannelGrain : Grain, IChannelGrain { - private readonly List<ChatMsg> _messages = new(100); - private readonly List<string> _onlineMembers = new(10); + private readonly List<ChatMsg> _messages = []; + private readonly List<string> _onlineMembers = []; - private IAsyncStream<ChatMsg> _stream = null!; + // Initialized in OnActivateAsync that runs before + // other methods that uses _stream field can be invoked. + private IAsyncStream<ChatMsg> _stream = default!; public override Task OnActivateAsync(CancellationToken cancellationToken) { var streamProvider = this.GetStreamProvider("chat"); - var streamId = StreamId.Create( - "ChatRoom", this.GetPrimaryKeyString()); + var streamId = StreamId.Create("ChatRoom", this.GetPrimaryKeyString()); - _stream = streamProvider.GetStream<ChatMsg>( - streamId); + _stream = streamProvider.GetStream<ChatMsg>(streamId); return base.OnActivateAsync(cancellationToken); } @@ -29,8 +28,8 @@ public async Task<StreamId> Join(string nickname) await _stream.OnNextAsync( new ChatMsg( - "System", - $"{nickname} joins the chat '{this.GetPrimaryKeyString()}' ...")); + Author: "System", + Text: $"{nickname} joins the chat '{this.GetPrimaryKeyString()}' ...")); return _stream.StreamId; } @@ -41,8 +40,8 @@ public async Task<StreamId> Leave(string nickname) await _stream.OnNextAsync( new ChatMsg( - "System", - $"{nickname} leaves the chat...")); + Author: "System", + Text: $"{nickname} leaves the chat...")); return _stream.StreamId; } @@ -51,6 +50,11 @@ public async Task<bool> Message(ChatMsg msg) { _messages.Add(msg); + if (_messages.Count > 100) + { + _messages.RemoveAt(0); + } + await _stream.OnNextAsync(msg); return true; diff --git a/orleans/ChatRoom/ChatRoom.Service/ChatRoom.Service.csproj b/orleans/ChatRoom/ChatRoom.Service/ChatRoom.Service.csproj index fd679dae667..758c234526a 100644 --- a/orleans/ChatRoom/ChatRoom.Service/ChatRoom.Service.csproj +++ b/orleans/ChatRoom/ChatRoom.Service/ChatRoom.Service.csproj @@ -1,7 +1,7 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0</TargetFramework> + <TargetFramework>net9.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <OutputType>Exe</OutputType> @@ -9,7 +9,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.Orleans.Server" Version="8.0.0" /> + <PackageReference Include="Microsoft.Orleans.Server" Version="9.0.1" /> </ItemGroup> <ItemGroup> diff --git a/orleans/ChatRoom/ChatRoom.Service/Program.cs b/orleans/ChatRoom/ChatRoom.Service/Program.cs index a49de0be839..3f9a80f6cab 100644 --- a/orleans/ChatRoom/ChatRoom.Service/Program.cs +++ b/orleans/ChatRoom/ChatRoom.Service/Program.cs @@ -1,11 +1,13 @@ -using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; await Host.CreateDefaultBuilder(args) .UseOrleans(siloBuilder => { - siloBuilder - .UseLocalhostClustering() + siloBuilder.UseLocalhostClustering() .AddMemoryGrainStorage("PubSubStore") - .AddMemoryStreams("chat"); + .AddMemoryStreams("chat") + .ConfigureLogging(logging => logging.AddConsole()); }) .RunConsoleAsync(); + diff --git a/orleans/ChatRoom/ChatRoom.slnLaunch b/orleans/ChatRoom/ChatRoom.slnLaunch new file mode 100644 index 00000000000..dcb30fbc541 --- /dev/null +++ b/orleans/ChatRoom/ChatRoom.slnLaunch @@ -0,0 +1,15 @@ +[ + { + "Name": "Run client and service", + "Projects": [ + { + "Path": "ChatRoom.Client\\ChatRoom.Client.csproj", + "Action": "Start" + }, + { + "Path": "ChatRoom.Service\\ChatRoom.Service.csproj", + "Action": "Start" + } + ] + } +] \ No newline at end of file diff --git a/orleans/ChatRoom/README.md b/orleans/ChatRoom/README.md index 99496bc2886..e60f4aa5d66 100644 --- a/orleans/ChatRoom/README.md +++ b/orleans/ChatRoom/README.md @@ -26,7 +26,7 @@ Each chat channel has a corresponding `ChannelGrain` which is identified by the ## Sample prerequisites -This sample is written in C# and targets .NET 8.0. It requires the [.NET 8.0 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) or later. +This sample is written in C# and targets .NET 9.0. It requires the [.NET 9.0 SDK](https://dotnet.microsoft.com/download/dotnet/9.0) or later. ## Building the sample