LoginSignup
1
1

More than 3 years have passed since last update.

Microsoft Orleans チュートリアル:最小の Orleans アプリケーションを作成する

Last updated at Posted at 2021-04-11

grain_formulation.png
堅牢でスケーラブルな分散アプリケーションのためのクロスプラットフォームフレームワーク Microsoft Orleans のチュートリアル Tutorial One - Creating a Minimal Orleans Application に従ってアプリケーションを実装する手順をメモっとく。

検証環境

  • Visual Studio 2019 16.9.3
    • インストール済みワークロード:.NET Core クロスプラットフォームの開発
  • Orleans 3.4.2

プロジェクトをセットアップする

下記に示す4つのプロジェクトを作成する。

  • Grain のインターフェイスを含む GrainInterfaces クラスライブラリプロジェクト
  • Grain の実装を含む Grains クラスライブラリプロジェクト
  • Silo をホストする Silo コンソールプロジェクト
  • クライアントになる Client コンソールプロジェクト

本節のセットアップが完了するとソリューションは最終的に下記のようになる。

image.png

構造を作成する

Silo コンソールアプリケーションを作成する。ソリューション名は Orleans Basics にする。ターゲットフレームワークは .NET Core 3.1 にする。

image.png
image.png
image.png
image.png

ソリューションを右クリックして、「追加」から「新しいプロジェクト」を選択し、Client コンソールアプリケーションを作成する。ターゲットフレームワークは .NET Core 3.1 にする。

image.png
image.png
image.png

同様に、GrainInterfaces クラスライブラリを作成する。ターゲットフレームワークは .NET Standard 2.1 にする。

image.png
image.png
image.png

同様に、Grains クラスライブラリを作成する。ターゲットフレームワークは .NET Standard 2.1 にする。

image.png
image.png
image.png

デフォルトソースファイルを削除する

GrainInterfaces プロジェクトの Class1.cs ファイルと Grains プロジェクトの Class1.cs ファイルを削除する。

参照を追加する

Grains プロジェクトの依存関係を右クリックし、「プロジェクト参照の追加」を選択する。Grains プロジェクトが GrainInterfaces プロジェクトを参照するように設定する。

image.png

同様に、Silo プロジェクトが GrainInterfaces プロジェクトと Grains プロジェクトを参照するように設定する。

image.png

同様に、Client プロジェクトが GrainInterfaces プロジェクトを参照するように設定する。

image.png

NuGet パッケージを追加する

下記の表にあるとおり各プロジェクトに NuGet パッケージを追加する。

プロジェクト NuGet パッケージ
Silo Microsoft.Orleans.Server
Silo Microsoft.Extensions.Logging.Console
Client Microsoft.Extensions.Logging.Console
Client Microsoft.Orleans.Client
GrainInterfaces Microsoft.Orleans.Core.Abstractions
GrainInterfaces Microsoft.Orleans.CodeGenerator.MSBuild
Grains Microsoft.Orleans.CodeGenerator.MSBuild
Grains Microsoft.Orleans.Core.Abstractions
Grains Microsoft.Extensions.Logging.Abstractions

例えば、Silo プロジェクトに Microsoft.Orleans.Server パッケージを追加するときは、Silo プロジェクトを右クリックし、「NuGet パッケージの管理」を選択する。「参照」タブを選択し、検索キーワードとして Microsoft.Orleans.Server を入力し、Microsoft.Orleans.Server パッケージを選択し、インストールをクリックする。

image.png

Grain インターフェイスを定義する

GrainInterfaces プロジェクトを右クリックし、「追加」から「新しい項目」を選択する。IHello インターフェイスを IHello.cs という名前で追加する。

image.png

IHello.cs を下記のように修正する。

using System.Threading.Tasks;

namespace OrleansBasics
{
    public interface IHello : Orleans.IGrainWithIntegerKey
    {
        Task<string> SayHello(string greeting);
    }
}

Grain クラスを定義する

Grains プロジェクトを右クリックし、「追加」から「新しい項目」を選択する。Grains プロジェクトに HelloGrain クラスを HelloGrain.cs という名前で追加する。

image.png

HelloGrain.cs を下記のように修正する。

using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace OrleansBasics
{
    public class HelloGrain : Orleans.Grain, IHello
    {
        private readonly ILogger logger;

        public HelloGrain(ILogger<HelloGrain> logger)
        {
            this.logger = logger;
        }

        Task<string> IHello.SayHello(string greeting)
        {
            logger.LogInformation($"\n SayHello message received: greeting = '{greeting}'");
            return Task.FromResult($"\n Client said: '{greeting}', so HelloGrain says: Hello!");
        }
    }
}

Silo を作成する

Silo プロジェクトの Program.cs を下記のように修正する。

using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Orleans;
using Orleans.Configuration;
using Orleans.Hosting;

namespace OrleansBasics
{
    public class Program
    {
        public static int Main(string[] args)
        {
            return RunMainAsync().Result;
        }

        private static async Task<int> RunMainAsync()
        {
            try
            {
                var host = await StartSilo();
                Console.WriteLine("\n\n Press Enter to terminate...\n\n");
                Console.ReadLine();

                await host.StopAsync();

                return 0;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return 1;
            }
        }

        private static async Task<ISiloHost> StartSilo()
        {
            // define the cluster configuration
            var builder = new SiloHostBuilder()
                .UseLocalhostClustering()
                .Configure<ClusterOptions>(options =>
                {
                    options.ClusterId = "dev";
                    options.ServiceId = "OrleansBasics";
                })
                .ConfigureApplicationParts(parts => parts.AddApplicationPart(typeof(HelloGrain).Assembly).WithReferences())
                .ConfigureLogging(logging => logging.AddConsole());

            var host = builder.Build();
            await host.StartAsync();
            return host;
        }
    }
}

Client を作成する

Client プロジェクトの Program.cs を下記のように修正する。

using Microsoft.Extensions.Logging;
using Orleans;
using Orleans.Configuration;
using System;
using System.Threading.Tasks;

namespace OrleansBasics
{
    public class Program
    {
        static int Main(string[] args)
        {
            return RunMainAsync().Result;
        }

        private static async Task<int> RunMainAsync()
        {
            try
            {
                using (var client = await ConnectClient())
                {
                    await DoClientWork(client);
                    Console.ReadKey();
                }

                return 0;
            }
            catch (Exception e)
            {
                Console.WriteLine($"\nException while trying to run client: {e.Message}");
                Console.WriteLine("Make sure the silo the client is trying to connect to is running.");
                Console.WriteLine("\nPress any key to exit.");
                Console.ReadKey();
                return 1;
            }
        }

        private static async Task<IClusterClient> ConnectClient()
        {
            IClusterClient client;
            client = new ClientBuilder()
                .UseLocalhostClustering()
                .Configure<ClusterOptions>(options =>
                {
                    options.ClusterId = "dev";
                    options.ServiceId = "OrleansBasics";
                })
                .ConfigureLogging(logging => logging.AddConsole())
                .Build();

            await client.Connect();
            Console.WriteLine("Client successfully connected to silo host \n");
            return client;
        }

        private static async Task DoClientWork(IClusterClient client)
        {
            // example of calling grains from the initialized client
            var friend = client.GetGrain<IHello>(0);
            var response = await friend.SayHello("Good morning, HelloGrain!");
            Console.WriteLine($"\n\n{response}\n\n");
        }
    }
}

アプリケーションを実行する

Silo プロジェクトを右クリックし、「デバッグ」から「新しいインスタンスの開始」を選択する。そうすると、下記のようなコンソールが表示され、大量の起動ログと共に Silo アプリケーションが起動する。

image.png

Silo アプリケーションを実行した状態で、折りたたまれているソリューションエクスプローラーにある Client プロジェクトを右クリックし、「デバッグ」から「新しいインスタンスの開始」を選択する。そうすると、下記のようなコンソールが表示され、Client アプリケーションが起動する。起動すると即座に Silo アプリケーションで動作している HelloGrain に SayHello メッセージを送信する。Client は "Good morning, HelloGrain!" をメッセージの引数として送信し、HelloGrain は "Hello!" と返信している。

image.png

Silo アプリケーションのコンソールにもログが記録され、"Good morning, HelloGrain!" という引数を伴う SayHello メッセージが届いたことを記録している。

image.png


今回は堅牢でスケーラブルな分散アプリケーションのためのクロスプラットフォームフレームワーク Microsoft Orleans のチュートリアル Tutorial One - Creating a Minimal Orleans Application に従ってアプリケーションを実装する手順について説明した。Orleans の有用性を示す実用的な例ではないので、今後は Orleans の実用性について理解を深めたい。

参考文献

https://github.com/dotnet/orleans
https://dotnet.github.io/orleans/

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1