Durable Functions での関数チェーン - Hello シーケンス サンプル

関数チェーンとは、特定の順序で一連の関数を実行するパターンです。 ある関数の出力が、別の関数の入力に適用される必要がある、ということがよくあります。 この記事では、Durable Functions のクイックスタート (C#JavaScriptTypeScriptPythonPowerShellJava) を実行するときに作成するチェーンのシーケンスについて説明します。 Durable Functions について詳しくは、「Durable Functions overview」(Durable Functions の概要) をご覧ください。

前提条件

Note

Azure Functions の Node.js プログラミング モデルのバージョン 4 は一般提供されています。 新しい v4 モデルは、JavaScript と TypeScript の開発者にとって、より柔軟で直感的なエクスペリエンスが得られるように設計されています。 v3 と v4 の違いの詳細については、移行ガイドを参照してください。

次のコード スニペットでは、JavaScript (PM4) は、新しいエクスペリエンスであるプログラミング モデル V4 を示しています。

関数

この記事では、サンプル アプリで使用されている次の関数について説明します。

  • E1_HelloSequence:1 つの オーケストレーター機能。1 つのシーケンスで E1_SayHello を複数回呼び出します。 E1_SayHello 呼び出しからの出力を格納し、結果を記録します。
  • E1_SayHello:文字列の先頭に "Hello" を付加する アクティビティ関数
  • HttpStart:オーケストレーターのインスタンスを起動する HTTP によってトリガーされる永続的なクライアント関数。

E1_HelloSequence オーケストレーター関数

[FunctionName("E1_HelloSequence")]
public static async Task<List<string>> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();

    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Tokyo"));
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Seattle"));
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello_DirectInput", "London"));

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

すべての C# オーケストレーション関数は、Microsoft.Azure.WebJobs.Extensions.DurableTask アセンブリにある DurableOrchestrationContext 型のパラメーターを持つ必要があります。 このコンテキスト オブジェクトでは、他のアクティビティ関数を呼び出し、その CallActivityAsync メソッドを使用して入力パラメーターを渡すことができます。

このコードでは、E1_SayHello を異なるパラメーター値で 3 回続けて呼び出します。 各呼び出しの戻り値が outputs 一覧に追加され、それが関数の末尾に返されます。

E1_SayHello アクティビティ関数

[FunctionName("E1_SayHello")]
public static string SayHello([ActivityTrigger] IDurableActivityContext context)
{
    string name = context.GetInput<string>();
    return $"Hello {name}!";
}

アクティビティは、ActivityTrigger 属性を使用します。 指定された IDurableActivityContext を使用して、GetInput<T> を使用した入力値へのアクセスなど、アクティビティ関連のアクションを実行します。

E1_SayHello の実装は、比較的単純な文字列の書式設定操作です。

IDurableActivityContextにバインドする代わりに、アクティビティ関数に渡される型に直接バインドすることができます。 次に例を示します。

[FunctionName("E1_SayHello_DirectInput")]
public static string SayHelloDirectInput([ActivityTrigger] string name)
{
    return $"Hello {name}!";
}

HttpStart クライアント関数

オーケストレーター関数のインスタンスを開始するには、クライアント関数を使用します。 E1_HelloSequence のインスタンスを開始するには、HttpStart HTTP によってトリガーされる関数を使用します。

public static class HttpStart
{
    [FunctionName("HttpStart")]
    public static async Task<HttpResponseMessage> Run(
        [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
        [DurableClient] IDurableClient starter,
        string functionName,
        ILogger log)
    {
        // Function input comes from the request content.
        object eventData = await req.Content.ReadAsAsync<object>();
        string instanceId = await starter.StartNewAsync(functionName, eventData);

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

        return starter.CreateCheckStatusResponse(req, instanceId);
    }
}

オーケストレーター操作をするには、関数に DurableClient 入力バインドが含まれている必要があります。 クライアントを使用して、オーケストレーションを開始します。 また、新しいオーケストレーションの状態を確認するための URL を含む HTTP 応答を返すこともできます。

サンプルを実行する

E1_HelloSequence オーケストレーションを実行するには、次の HTTP POST 要求を HttpStart 関数に送信します。

POST http://{host}/orchestrators/E1_HelloSequence

Note

前の HTTP スニペットでは、既定の api/ プレフィックスをすべての HTTP トリガー関数 URL から削除するエントリが host.json ファイルにあることを想定しています。 この構成のマークアップはサンプルの host.json ファイルにあります。

たとえば、"myfunctionapp" という関数アプリのサンプルを実行する場合、"{host}" を "myfunctionapp.azurewebsites.net" に置き換えます。

結果は次のような HTTP 202 応答です (簡潔にするため省略しています)。

HTTP/1.1 202 Accepted
Content-Length: 719
Content-Type: application/json; charset=utf-8
Location: http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}

(...trimmed...)

この時点で、オーケストレーションはキューに登録され、すぐに実行を開始します。 Location ヘッダー内の URL は、実行状態を確認するのに使用できます。

GET http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}

この結果がオーケストレーションの状態です。 迅速に実行して完了し、次のような応答で完了状態にあることがわかります(簡潔にするため省略しています)。

HTTP/1.1 200 OK
Content-Length: 179
Content-Type: application/json; charset=utf-8

{"runtimeStatus":"Completed","input":null,"output":["Hello Tokyo!","Hello Seattle!","Hello London!"],"createdTime":"2017-06-29T05:24:57Z","lastUpdatedTime":"2017-06-29T05:24:59Z"}

このように、インスタンスの runtimeStatus完了しており、output は orchestrator 関数の実行の JSON でシリアル化された結果を格納します。

Note

同様のスターター ロジックを queueTriggereventHubTriggertimerTrigger などの他のトリガーの種類に実装することができます。

関数の実行ログを確認しましょう。 E1_HelloSequence 関数が、オーケストレーションの信頼性に関するトピックで説明されている再生の動作のため、複数回、開始し完了しています。 その一方で、E1_SayHello の実行は 3 回だけでした。これらの関数の実行は再生されなかったためです。

次のステップ

このサンプルでは、単純な関数チェーンのオーケストレーションについて説明しました。 次のサンプルでは、ファンアウト/ファンイン パターンの実装方法について説明します。