Posted at

Durable Functions Getting Started - C#

Visual Studio を使って初めての Durable Functions を書いてみましょう。


前提条件

下記のリンクに、Visual Studio を用いて開発を行うための前提条件が書かれています。内容がたまにアップデートされるので、ここで詳細は書かず、リンクにとどめておきます。丁寧にかいてありますので、この前提条件に従うと問題ないとおもいます。

ポイントだけを説明しておきますと

の三点がそろっていれば大丈夫かと思います。


Azure Functions (V2) プロジェクトを作成する

Azure Functions は、V1 と V2 が存在します。詳しくはAzure Functions ランタイム バージョンの概要をご参照ください。今後は V2 の使用をお勧めしますので、この手順は V2 について書かせていただきます。

a. Visual Studio で、[ファイル] メニューから [新規] > [プロジェクト] の順に選択します。

b. [新しいプロジェクト] ダイアログで、[インストール済み] を選択し、[Visual C#] > [クラウド] の順に展開して [Azure Functions] を選択します。プロジェクトの名前を入力して、[OK] をクリックします。 関数アプリ名は、C# 名前空間として有効である必要があります。そのため、アンダースコア、ハイフン、その他の英数字以外の文字は使用しないでください。



c. 図の下の表に示した設定を使用してください。

Settings
推奨値
説明

バージョン
Azure Functions 2.x (.NET Core)
これは、.NET Core をサポートする Azure Functions のバージョン 2.x ランタイムを使用する関数プロジェクトを作成します。 Azure Functions 1.x では、.NET Framework がサポートされます。 詳細については、「Azure Functions ランタイム バージョンをターゲットにする方法」をご覧ください。

テンプレート
Empty
Azure Functions 2.x では現在のところテンプレートがサポートされていません。

ストレージ アカウント
Storage Emulator (ストレージ エミュレーター)
Durable Functions は、ストレージアカウントを使用します。Azure 開発をインストールすると自動的にインストールされる Azure Storage エミュレータをローカル開発では使用します。

d. [OK] をクリックして、関数プロジェクトを作成します。


Durable Functions を作成する

a. ソリューション エクスプローラーで、プロジェクト ノードを右クリックし、[追加] > [新しいアイテム] の順に選択します。 [Azure 関数] を選択します。次のような画面がでてきますので、Durable Functions Orchestration を選択して、[追加] を選択します。Durable Functions のテンプレートが作成され、Microsoft.Azure.WebJobs.Extensions.DurableTask nuget パッケージがインストールされます。


nuget パッケージの更新

デフォルトでは、nuget パッケージのバージョンが古くなっています。ソリューション エクスプローラーで、プロジェクト ノードを右クリックし、[Nuget パッケージの管理] を選択します。

[更新] タブに数字がでている場合は、[更新]タブをクリックします。インストール済みの nuget パッケージのうち更新が必要なものが表示されます。この例では、Microsoft.NET.Sdk.Functions が古いバージョンになっていますので、右のパネルの [更新] をクリックしてバージョンを更新します。

Durable Functions のコードができたので実行することができます。


Durable Functions をローカルでテストする

Azure Functions Core Tools](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-run-local)をつかうとローカルの開発用コンピューター上で Azure Functions プロジェクトを実行できます。 Visual Studio から初めて関数を開始すると、これらのツールをインストールするよう求めるメッセージが表示されます。

関数をテストするには、F5 キーを押します。 メッセージが表示されたら、Visual Studio からの要求に同意し、Azure Functions Core (CLI) ツールをダウンロードしてインストールします。 また、ツールで HTTP 要求を処理できるようにファイアウォールの例外を有効にすることが必要になる場合もあります。

Azure Functions のランタイムの出力から、関数の URL をコピーします。

Durable Functions が起動し、リクエストを受け付ける準備がなされました。


コードを理解する

Durable Functions のオーケストレーションを開始します。生成されたコードを読んでみます。


Http トリガと Orchestration Client

この関数は、Httpリクエストを受け付ける HttpTrigger とともに、DurableOrchestrationClient のインスタンスを受け取っています。この DurableOrchestrationClientStartNewAsync("関数名", null) メソッドを呼び出すことで、オーケストレーションが開始されます。オーケストレーションのinstanceIdが自動的に生成され、FunctionName アトリビュートHelloWorld の関数が開始されます。

        [FunctionName("HelloWorld_HttpStart")]

public static async Task<HttpResponseMessage> HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")]HttpRequestMessage req,
[OrchestrationClient]DurableOrchestrationClient starter,
ILogger log)
{
// Function input comes from the request content.
string instanceId = await starter.StartNewAsync("HelloWorld", null);

log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

return starter.CreateCheckStatusResponse(req, instanceId);
}


オーケストレータ

StartNewAsync の開始をうけて、オーケストレーションが開始されます。DurableOrchestrationContext のインスタンスが引き渡されます。context オブジェクトには、先行する関数から引き渡された引数(この例では、null)等が格納されています。context.CallActivityAsync<T>("Activity 関数名", "引数") を呼び出すことで、本オーケストレータ関数から、アクティビティ関数を呼び出して、処理を実行させることができます。引数の型を<T> で指定する必要があります。本実行は一件普通のメソッド呼び出しに見えますが、実際は、Queue を介してメッセージ送信が行われています。オーケストレータ関数には、[OrchestrationTrigger] アトリビュートが必要になります。本関数の戻り値がオーケストレーションの結果として引き渡されます。

        [FunctionName("HelloWorld")]

public static async Task<List<string>> RunOrchestrator(
[OrchestrationTrigger] DurableOrchestrationContext context)
{
var outputs = new List<string>();

// Replace "hello" with the name of your Durable Activity Function.
outputs.Add(await context.CallActivityAsync<string>("HelloWorld_Hello", "Tokyo"));
outputs.Add(await context.CallActivityAsync<string>("HelloWorld_Hello", "Seattle"));
outputs.Add(await context.CallActivityAsync<string>("HelloWorld_Hello", "London"));

// returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
return outputs;
}


アクティビティ

オーケストレータから呼び出された 関数です。Azure Functions のバインディング も使用することができます。本関数がオーケストレータのCallActivityAsync<T>() から呼び出されて実行された際のパラメータが、[ActivityTrigger] アトリビュートで引き渡される引数になります。戻り値はCallActivityAsync<T>()関数の戻り値になります。

        [FunctionName("HelloWorld_Hello")]

public static string SayHello([ActivityTrigger] string name, ILogger log)
{
log.LogInformation($"Saying hello to {name}.");
return $"Hello {name}!";
}


オーケストレーションを開始する

Durable Functions をローカルでテストする で Durable Fucntions が起動しています。Postmanをダウンロードして、先ほどのURLにリクエストを送信します。Durable Functions をローカルでテストする の章でコピーした、URL をテキストボックスに張り付けて、[Send] を選択します。

バックグラウンドでは、Durable Functions が非同期に実行されています。

しばらくすると、Postman に結果が返ってきます。これは、処理が終了したという意味ではなく、リクエストの受付が終了したという意味で、バックグラウンドで、オーケストレーションが実行されています。


ステータスを確認する

statusQueryGetUri のリンクをクリックして、[Send] を選択します。このリンクにより、実行されたオーケストレーションのステータスを確認することができます。

オーケストレーションの実行結果が output に表示されます。

項目
説明

instanceId
オーケストレーションのId。自動発行されるが、StartAsNew() で指定も可能

runtimeStatus
オーケストレーションの実行状態 Running, Completed, Failure, Terminated 等

input
オーケストレーションのパラメータ StartAsNew() で指定された引数)

cutomStatus
カスタムのステータス

output
オーケストレーションの実行結果

createdTime
オーケストレーションの開始時間

latelyUpdatedTime
オーケストレーションが最後に動作した時間


次のステップ

Durable Functions のコーディングの詳細は、Durable Functions の概要 をご参照ください。ローカルで作成した関数のデバッグや、Azure へのデプロイ方法は Visual Studio を使用する Azure Functions の開発をごらんください。


Azure Functions の実行で Could not load file or assembly 問題が起きたら