最近「Azure Functions」がらみでよく話に出る「Durable Function」のクイックスタートをやってみました。
備忘録的に作った際のメモを残そうと思います。
Durable Functions の概要
概要については公式ページ参照 docs.microsoft.com
Durable Functions の主な用途は、サーバーレス アプリケーションにおける複雑でステートフルな調整の問題をシンプルにすることです。 次のセクションでは、Durable Functions を使用することでメリットがある、いくつかの典型的なアプリケーションのパターンを示します。
パターン #1: 関数チェーン
パターン #2: ファンアウト/ファンイン
パターン #3: 非同期 HTTP API
パターン #4: 監視
パターン #5: 人による操作
Azure Functionsを連続、並列で実行したりする機能なのかなぁってイメージです。
機能、事例とかを知るためにTechSummit2018でMicrosoftの牛尾さんがDurable Functionsのセッションやってたから見てみようかなと思っています。
さらっと作ってみた
Azure Functionsのプロジェクトを作る
Visual Studioから作ります。
新しいプロジェクトで「Visual C#」→「Cloud」→「Azure Functions」
バージョンを「Azure Functions v2(.NET Core)」
テンプレートは「なし」
ストレージアカウントは「ストレージエミュレーター」
プロジェクトに新しい関数を追加する
「プロジェクトを右クリック」→「追加」→「新しいAzure関数...」
「Azure関数」を選択し、名前を付けて追加をクリック
「Durable Functions Orchestration」を選択してOKを選択する
下記のようなDurable Functionsのコードが自動生成される。
using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.Azure.WebJobs.Host; using Microsoft.Extensions.Logging; namespace DurableFuncApp { public static class Function1 { [FunctionName("Function1")] 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>("Function1_Hello", "Tokyo")); outputs.Add(await context.CallActivityAsync<string>("Function1_Hello", "Seattle")); outputs.Add(await context.CallActivityAsync<string>("Function1_Hello", "London")); // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"] return outputs; } [FunctionName("Function1_Hello")] public static string SayHello([ActivityTrigger] string name, ILogger log) { log.LogInformation($"Saying hello to {name}."); return $"Hello {name}!"; } [FunctionName("Function1_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("Function1", null); log.LogInformation($"Started orchestration with ID = '{instanceId}'."); return starter.CreateCheckStatusResponse(req, instanceId); } } }
HttpStartで関数を起動し、RunOrchestrator(名前はFunction1)で
「Function1_Hello」関数を3回連続で実行するコードみたいですね。
デバッグ実行で試す
デバッグ実行に成功すると、ローカルホストのURLが出力されるので、
このURLをブラウザ上で実行する。
ブラウザ上でURLをたたくと下記のような文字列が出力される。
{"id":"4fbb74e39ae04151a6fce230198617f4","statusQueryGetUri":"http://localhost:7071/runtime/webhooks/durabletask/instances/4fbb74e39ae04151a6fce230198617f4?taskHub=DurableFunctionsHub&connection=Storage&code=JJ8MNcYXpnllJD4LkpJdXQ3/jSbW0R0qad/Hs3W/PayFCSlrf5V/2w==","sendEventPostUri":"http://localhost:7071/runtime/webhooks/durabletask/instances/4fbb74e39ae04151a6fce230198617f4/raiseEvent/{eventName}?taskHub=DurableFunctionsHub&connection=Storage&code=JJ8MNcYXpnllJD4LkpJdXQ3/jSbW0R0qad/Hs3W/PayFCSlrf5V/2w==","terminatePostUri":"http://localhost:7071/runtime/webhooks/durabletask/instances/4fbb74e39ae04151a6fce230198617f4/terminate?reason={text}&taskHub=DurableFunctionsHub&connection=Storage&code=JJ8MNcYXpnllJD4LkpJdXQ3/jSbW0R0qad/Hs3W/PayFCSlrf5V/2w==","rewindPostUri":"http://localhost:7071/runtime/webhooks/durabletask/instances/4fbb74e39ae04151a6fce230198617f4/rewind?reason={text}&taskHub=DurableFunctionsHub&connection=Storage&code=JJ8MNcYXpnllJD4LkpJdXQ3/jSbW0R0qad/Hs3W/PayFCSlrf5V/2w=="}
上記文字列の中から「statusQueryGetUri」をコピーし、ブラウザ上で実行すると実行結果が表示されました。
出力結果
"Hello Tokyo!","Hello Seattle!","Hello London!"
が出力されており、
「Function1_Hello」関数が3連続で呼ばれていることがわかりました。
{"instanceId":"4fbb74e39ae04151a6fce230198617f4","runtimeStatus":"Completed","input":null,"customStatus":null,"output":["Hello Tokyo!","Hello Seattle!","Hello London!"],"createdTime":"2018-12-10T08:58:29Z","lastUpdatedTime":"2018-12-10T08:58:37Z"}
Azureに発行する
発行する方法はいつもと変わらないので省略します。
動作は、デバッグ実行時と変わりません。