Durable Functions のバインド (Azure Functions)

Durable Functions 拡張機能には、オーケストレーター関数、エンティティ関数、アクティビティ関数の実行を制御する 3 つの新しいトリガーのバインドが導入されています。 Durable Functions ランタイムのクライアントとして機能する出力バインドも導入されています。

オーケストレーション トリガー

オーケストレーション トリガーを使用して、永続的なオーケストレーター関数を作成できます。 このトリガーは、新しいオーケストレーション インスタンスのスケジュールが設定されたときと、既存のオーケストレーション インスタンスでイベントが受信されたときに実行されます。 オーケストレーター関数がトリガーされる可能性があるイベントの例としては、永続的なタイマーの有効期限、アクティビティ関数の応答、外部クライアントによって発生したイベントがあります。

.NET で関数を作成すると、OrchestrationTriggerAttribute .NET 属性を使用して、オーケストレーション トリガーが構成されます。

オーケストレーター関数を (JavaScript、Python、PowerShell などの) スクリプト言語で記述する場合、オーケストレーション トリガーは、function.json ファイルの bindings 配列の次の JSON オブジェクトによって定義されます。

{
    "name": "<Name of input parameter in function signature>",
    "orchestration": "<Optional - name of the orchestration>",
    "type": "orchestrationTrigger",
    "direction": "in"
}
  • orchestration は、クライアントがこのオーケストレーター関数の新しいインスタンスを開始するときに使用する必要がある、オーケストレーションの名前です。 このプロパティは省略可能です。 指定されない場合は関数の名前が使用されます。

内部的には、このトリガー バインドによって、オーケストレーション開始イベント、永続的なタイマーの有効期限のイベント、アクティビティ関数の応答イベント、他の関数によって発生した外部イベントなど、新しいオーケストレーション イベントについて、構成された永続ストアがポーリングされます。

トリガーの動作

オーケストレーション トリガーについての注意事項を次に示します。

  • シングル スレッド - 1 つのホスト インスタンスのすべてのオーケストレーター関数の実行で単一のディスパッチャー スレッドが使用されます。 このため、オーケストレーター関数コードが効率的であり、I/O の実行がないことを保証することが重要です。 さらに、このスレッドが、Durable Functions 固有のタスクの種類のために待機しているとき以外は、非同期操作を行わないことを保証することも重要です。
  • 有害メッセージの処理 - オーケストレーション トリガーでは、有害メッセージはサポートされません。
  • メッセージの可視性 - オーケストレーション トリガー メッセージはキューから削除され、構成可能な期間にわたって非表示を保持します。 これらのメッセージの可視性は、関数アプリが正常に実行されている限り、自動的に更新されます。
  • 戻り値 - 戻り値は JSON にシリアル化され、Azure Table Storage のオーケストレーション履歴テーブルに保存されます。 これらの戻り値は、オーケストレーション クライアントのバインドによるクエリを実行できます。これについては、後で説明します。

警告

オーケストレーター関数は、オーケストレーション トリガーのバインドを除いて、入力または出力バインドを使用しないでください。 これらのバインドはシングル スレッド ルールと I/O ルールに従っていない可能性があるため、これらのバインドを実行すると、Durable Task 拡張機能で問題が発生する可能性があります。 他のバインドを使用する場合は、オーケストレーター関数から呼び出されたアクティビティ関数にそれらを追加します。 オーケストレーター関数のコーディングの制約について詳しくは、「オーケストレーター関数のコードの制約」のドキュメントをご覧ください。

警告

JavaScript と Python のオーケストレーター関数は、async で宣言されてはなりません。

トリガーの使用方法

オーケストレーション トリガーのバインドは、入力と出力の両方をサポートします。 入力と出力の処理に関する注意事項を次に示します。

  • 入力 - オーケストレーション トリガーは、コンテキスト入力オブジェクトを介してアクセスされる入力を使用して呼び出すことができます。 すべての入力は、JSON にシリアル化できる必要があります。
  • 出力 - オーケストレーション トリガーは、入力と同じように出力値をサポートします。 関数の戻り値は、出力値を割り当てるために使用され、JSON にシリアル化できる必要があります。

トリガー サンプル

最もシンプルな "Hello World" オーケストレーター関数のコードの例を次に示します。

[FunctionName("HelloWorld")]
public static string Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    string name = context.GetInput<string>();
    // ... do some work ...
    return $"Hello {name}!";
}

注意

前のコードは Durable Functions 2.x 用です。 Durable Functions 1.x の場合、IDurableOrchestrationContext の代わりに DurableOrchestrationContext を使用する必要があります。 バージョン間の相違点の詳細については、Durable Functions のバージョンに関する記事を参照してください。

オーケストレーター関数の大半はアクティビティ関数を呼び出すため、"Hello World" の例でアクティビティ関数を呼び出す方法を示します。

[FunctionName("HelloWorld")]
public static async Task<string> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    string name = context.GetInput<string>();
    string result = await context.CallActivityAsync<string>("SayHello", name);
    return result;
}

注意

前のコードは Durable Functions 2.x 用です。 Durable Functions 1.x の場合、IDurableOrchestrationContext の代わりに DurableOrchestrationContext を使用する必要があります。 バージョン間の相違点の詳細については、Durable Functions のバージョンに関する記事を参照してください。

アクティビティ トリガー

アクティビティ トリガーを使用すると、オーケストレーター関数によって呼び出される関数 (アクティビティ関数と呼ばれる) を作成できます。

.NET を使用して関数を作成する場合、アクティビティ トリガーは ActvityTriggerAttribute .NET 属性を使用して構成されます。

JavaScript、Python、または PowerShell を使用する場合、アクティビティ トリガーは、function.jsonbindings 配列の次の JSON オブジェクトによって定義されます。

{
    "name": "<Name of input parameter in function signature>",
    "activity": "<Optional - name of the activity>",
    "type": "activityTrigger",
    "direction": "in"
}
  • activity はアクティビティの名前です。 この値は、オーケストレーター関数がこのアクティビティ関数を呼び出すために使用する名前です。 このプロパティは省略可能です。 指定されない場合は関数の名前が使用されます。

内部的には、このトリガー バインドによって、構成された永続ストアに対して新しいアクティビティ実行イベントがポーリングされます。

トリガーの動作

アクティビティ トリガーに関する注意事項を次に示します。

  • スレッド処理 - オーケストレーション トリガーとは異なり、アクティビティ トリガーにはスレッド処理と I/O に関する制限はありません。 それらは、標準的な関数と同様に扱うことができます。
  • 有害メッセージの処理 - アクティビティ トリガーには、有害メッセージのサポートはありません。
  • メッセージの可視性 - アクティビティ トリガー メッセージはキューから削除され、構成可能な期間にわたって非表示を保持します。 これらのメッセージの可視性は、関数アプリが正常に実行されている限り、自動的に更新されます。
  • 戻り値 - 戻り値は JSON にシリアル化され、構成された永続ストアに保存されます。

トリガーの使用方法

アクティビティ トリガーのバインドは、オーケストレーション トリガーと同じように、入力と出力の両方をサポートします。 入力と出力の処理に関する注意事項を次に示します。

  • 入力 - アクティビティ トリガーは、オーケストレーター関数からの入力を使用して呼び出すことができます。 すべての入力は、JSON にシリアル化できる必要があります。
  • 出力 - アクティビティ関数は、入力と同じように出力値をサポートします。 関数の戻り値は、出力値を割り当てるために使用され、JSON にシリアル化できる必要があります。
  • メタデータ - .NET アクティビティ関数を string instanceId パラメーターにバインドして、呼び出し元オーケストレーションのインスタンス ID を取得できます。

トリガー サンプル

シンプルな SayHello アクティビティ関数のコードの例を次に示します。

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

.NET の ActivityTriggerAttribute バインディングの既定のパラメーター型は IDurableActivityContext (Durable Functions v1 の場合は DurableActivityContext) です。 ただし、.NET アクティビティ トリガーは、JSON にシリアル化できる型 (プリミティブ型を含む) への直接的なバインドもサポートしているため、同じ関数を次のように単純化できます。

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

入出力バインドを使用する

アクティビティ トリガーのバインドに加えて、通常の入出力バインドを使用できます。 たとえば、アクティビティ バインドへの入力を取得し、EventHub 出力バインドを使用して EventHub にメッセージを送信できます。

{
  "bindings": [
    {
      "name": "message",
      "type": "activityTrigger",
      "direction": "in"
    },
    {
      "type": "eventHub",
      "name": "outputEventHubMessage",
      "connection": "EventhubConnectionSetting",
      "eventHubName": "eh_messages",
      "direction": "out"
  }
  ]
}
module.exports = async function (context) {
    context.bindings.outputEventHubMessage = context.bindings.message;
};

オーケストレーション クライアント

オーケストレーション クライアントのバインドを使用すると、オーケストレーター関数とやりとりする関数を記述できます。 これらの関数は、多くの場合、クライアント関数と呼ばれます。 たとえば、次のようにオーケストレーション インスタンスを操作できます。

  • インスタンスを開始する。
  • インスタンスの状態をクエリする。
  • インスタンスを終了する。
  • インスタンスの実行中にイベントを送信する。
  • インスタンスの履歴を消去します。

.NET を使用する場合は、DurableClientAttribute 属性 (Durable Functions v1.x の場合は OrchestrationClientAttribute) を使用して、オーケストレーション クライアントにバインドできます。

JavaScript、Python、PowerShell などのスクリプト言語を使用する場合、永続的なクライアント トリガーは、function.jsonbindings 配列の次の JSON オブジェクトによって定義されます。

{
    "name": "<Name of input parameter in function signature>",
    "taskHub": "<Optional - name of the task hub>",
    "connectionName": "<Optional - name of the connection string app setting>",
    "type": "orchestrationClient",
    "direction": "in"
}
  • taskHub - 複数の関数アプリが同じストレージ アカウントを共有するが、相互に分離する必要があるシナリオで使用されます。 指定されていない場合は、host.json の既定値が使用されます。 この値は、ターゲットのオーケストレーター関数によって使用される値と一致している必要があります。
  • connectionName - ストレージ アカウント接続文字列を含むアプリ設定の名前。 この接続文字列で表されるストレージ アカウントは、ターゲットのオーケストレーター関数によって使用されるものと同じにする必要があります。 指定されない場合は、関数アプリの既定のストレージ アカウント接続文字列が使用されます。

注意

ほとんどの場合、これらのプロパティを省略し、既定の動作を使用することをお勧めします。

クライアントの使用

.NET 関数では、通常は IDurableClient (Durable Functions v1.x の場合は DurableOrchestrationClient) にバインドします。これにより、Durable Functions によってサポートされるすべてのオーケストレーション クライアント API にフル アクセスできます。 他の言語では、その言語に固有の SDK を使用してクライアント オブジェクトにアクセスする必要があります。

"HelloWorld" オーケストレーションを開始する、キューによってトリガーされる関数の例を次に示します。

[FunctionName("QueueStart")]
public static Task Run(
    [QueueTrigger("durable-function-trigger")] string input,
    [DurableClient] IDurableOrchestrationClient starter)
{
    // Orchestration input comes from the queue message content.
    return starter.StartNewAsync("HelloWorld", input);
}

注意

前記の C# コードは Durable Functions 2.x 用です。 Durable Functions 1.x では、DurableClient 属性の代わりに OrchestrationClient 属性を使用する必要があります。また、IDurableOrchestrationClient ではなく DurableOrchestrationClient パラメーター型を使用する必要があります。 バージョン間の相違点の詳細については、Durable Functions のバージョンに関する記事を参照してください。

インスタンスの開始の詳細については、インスタンスの管理に関する記事を参照してください。

エンティティ トリガー

エンティティ トリガーを使用すると、エンティティ関数を作成できます。 このトリガーでは、特定のエンティティ インスタンスのイベントの処理がサポートされています。

注意

エンティティ トリガーは、Durable Functions 2.x 以降で使用できます。

内部的には、このトリガー バインドによって、実行する必要がある新しいエンティティ操作について、構成された永続ストアがポーリングされます。

トリガーの動作

エンティティ トリガーに関する注意事項を次に示します。

  • シングルスレッド: 特定のエンティティに対する操作を処理する場合は、単一のディスパッチャー スレッドが使用されます。 複数のメッセージが同時に 1 つのエンティティに送信される場合、操作は一度に 1 つずつ処理されます。
  • 有害メッセージの処理 - エンティティ トリガーには、有害メッセージのサポートはありません。
  • メッセージの可視性 - エンティティ トリガー メッセージはキューから削除され、構成可能な期間にわたって非表示を保持します。 これらのメッセージの可視性は、関数アプリが正常に実行されている限り、自動的に更新されます。
  • 戻り値 - エンティティ関数では戻り値をサポートしません。 特定の API を使用することで、状態を保存したり、オーケストレーションに値を渡したりすることができます。

実行中にエンティティに対して行われた状態の変更はいずれも、実行の完了後も自動的に保持されます。

エンティティ トリガーの定義と操作の詳細と例について詳しくは、持続エンティティに関するドキュメントをご覧ください。

エンティティ クライアント

エンティティ クライアント バインディングを使用すると、エンティティ関数を非同期的にトリガーできます。 これらの関数は、クライアント関数と呼ばれることもあります。

.NET にプリコンパイル済みの関数を使用する場合は、DurableClientAttribute .NET 属性を使用してエンティティ クライアントにバインドできます。

注意

また、[DurableClientAttribute] を使用して、オーケストレーション クライアントにバインドすることもできます。

スクリプト言語 (C# スクリプト、JavaScript、Python など) を開発に使用する場合、エンティティ トリガーは、function.jsonbindings 配列の次の JSON オブジェクトによって定義されます。

{
    "name": "<Name of input parameter in function signature>",
    "taskHub": "<Optional - name of the task hub>",
    "connectionName": "<Optional - name of the connection string app setting>",
    "type": "durableClient",
    "direction": "in"
}
  • taskHub - 複数の関数アプリが同じストレージ アカウントを共有するが、相互に分離する必要があるシナリオで使用されます。 指定されていない場合は、host.json の既定値が使用されます。 この値は、ターゲットのエンティティ関数によって使用される値と一致している必要があります。
  • connectionName - ストレージ アカウント接続文字列を含むアプリ設定の名前。 この接続文字列で表されるストレージ アカウントは、ターゲットのエンティティ関数によって使用されるものと同じにする必要があります。 指定されない場合は、関数アプリの既定のストレージ アカウント接続文字列が使用されます。

注意

ほとんどの場合、オプションのプロパティを省略し、既定の動作を使用することをお勧めします。

エンティティをクライアントとして操作する方法の詳細と例について詳しくは、持続エンティティに関するドキュメントをご覧ください。

host.json 設定

Durable Functions の構成設定。

注意

Durable Functions のすべてのメジャー バージョンは、Azure Functions ランタイムのすべてのバージョンでサポートされています。 ただし、host.json 構成のスキーマは、Azure Functions ランタイムのバージョンと使用する Durable Functions 拡張機能のバージョンによって若干異なります。 次の例は、Azure Functions 2.0 および3.0 で使用するためのものです。 どちらの例でも、Azure Functions 1.0 を使用している場合、使用可能な設定は同じですが、host.json の "durableTask" セクションは、"extensions" の下のフィールドとしてではなく、host.json 構成のルートに配置する必要があります。

Durable Functions 2.x

{
 "extensions": {
  "durableTask": {
    "hubName": "MyTaskHub",
    "storageProvider": {
      "connectionStringName": "AzureWebJobsStorage",
      "controlQueueBatchSize": 32,
      "controlQueueBufferThreshold": 256,
      "controlQueueVisibilityTimeout": "00:05:00",
      "maxQueuePollingInterval": "00:00:30",
      "partitionCount": 4,
      "trackingStoreConnectionStringName": "TrackingStorage",
      "trackingStoreNamePrefix": "DurableTask",
      "useLegacyPartitionManagement": true,
      "workItemQueueVisibilityTimeout": "00:05:00",
    },
    "tracing": {
      "traceInputsAndOutputs": false,
      "traceReplayEvents": false,
    },
    "notifications": {
      "eventGrid": {
        "topicEndpoint": "https://topic_name.westus2-1.eventgrid.azure.net/api/events",
        "keySettingName": "EventGridKey",
        "publishRetryCount": 3,
        "publishRetryInterval": "00:00:30",
        "publishEventTypes": [
          "Started",
          "Pending",
          "Failed",
          "Terminated"
        ]
      }
    },
    "maxConcurrentActivityFunctions": 10,
    "maxConcurrentOrchestratorFunctions": 10,
    "extendedSessionsEnabled": false,
    "extendedSessionIdleTimeoutInSeconds": 30,
    "useAppLease": true,
    "useGracefulShutdown": false
  }
 }
}

Durable Functions 1.x

{
  "extensions": {
    "durableTask": {
      "hubName": "MyTaskHub",
      "controlQueueBatchSize": 32,
      "partitionCount": 4,
      "controlQueueVisibilityTimeout": "00:05:00",
      "workItemQueueVisibilityTimeout": "00:05:00",
      "maxConcurrentActivityFunctions": 10,
      "maxConcurrentOrchestratorFunctions": 10,
      "maxQueuePollingInterval": "00:00:30",
      "azureStorageConnectionStringName": "AzureWebJobsStorage",
      "trackingStoreConnectionStringName": "TrackingStorage",
      "trackingStoreNamePrefix": "DurableTask",
      "traceInputsAndOutputs": false,
      "logReplayEvents": false,
      "eventGridTopicEndpoint": "https://topic_name.westus2-1.eventgrid.azure.net/api/events",
      "eventGridKeySettingName":  "EventGridKey",
      "eventGridPublishRetryCount": 3,
      "eventGridPublishRetryInterval": "00:00:30",
      "eventGridPublishEventTypes": ["Started", "Completed", "Failed", "Terminated"]
    }
  }
}

タスク ハブの名前は、先頭文字をアルファベットとする必要があります。また、使用できるのはアルファベットと数値だけです。 指定しない場合、関数アプリの既定のタスク ハブ名は DurableFunctionsHub です。 詳細については、タスク ハブに関するページをご覧ください。

プロパティ Default 説明
hubName DurableFunctionsHub 代替タスク ハブ名を使用すると、複数の Durable Functions アプリケーションが同じストレージ バックエンドを使用している場合でも、これらのアプリケーションを互いに分離できます。
controlQueueBatchSize 32 コントロール キューから一度にプルするメッセージの数。
controlQueueBufferThreshold Python の従量課金プラン: 32
JavaScript および C# の従量課金プラン: 128
専用プランまたは Premium プラン: 256
一度にメモリにバッファー処理できる制御キュー メッセージの数。その時点で、ディスパッチャーは、追加のメッセージがデキューされるまで待機します。
partitionCount 4 コントロール キューのパーティション数。 1 から 16 までの正の整数を使用できます。
controlQueueVisibilityTimeout 5 分 デキューされたコントロール キュー メッセージの表示タイムアウト。
workItemQueueVisibilityTimeout 5 分 デキューされた作業項目キュー メッセージの表示タイムアウト。
maxConcurrentActivityFunctions 従量課金プラン: 10
専用プランまたは Premium プラン: 現在のマシンのプロセッサ数の 10 倍
1 つのホスト インスタンスで同時に処理できるアクティビティ関数の最大数。
maxConcurrentOrchestratorFunctions 従量課金プラン: 5
専用プランまたは Premium プラン: 現在のマシンのプロセッサ数の 10 倍
1 つのホスト インスタンスで同時に処理できるオーケストレーター関数の最大数。
maxQueuePollingInterval 30 秒 コントロールおよび作業項目キューの最大ポーリング間隔 (hh:mm:ss 形式)。 値が高くなるほどメッセージ処理の待機時間が長くなる可能性があります。 値が低くなるほどストレージ コストが高くなる可能性があります。これは、ストレージ トランザクションが増加するからです。
azureStorageConnectionStringName AzureWebJobsStorage 基になる Azure Storage リソースの管理に使用される Azure Storage 接続文字列を含むアプリ設定の名前。
azureStorageConnectionStringName 履歴テーブルとインスタンス テーブルに使用する接続文字列の名前。 指定しない場合は、connectionStringName (Durable 2.x) または azureStorageConnectionStringName (Durable 1.x) 接続が使用されます。
trackingStoreNamePrefix trackingStoreConnectionStringName が指定されているときに履歴テーブルとインスタンス テーブルに使用されるプレフィックス。 設定されていない場合、既定のプレフィックス値は DurableTask になります。 trackingStoreConnectionStringName が指定されていない場合、履歴テーブルとインスタンス テーブルは hubName 値をプレフィックスとして使用し、trackingStoreNamePrefix の設定はすべて無視されます。
traceInputsAndOutputs false 関数呼び出しの入力と出力をトレースするかどうかを示す値。 関数の実行イベントをトレースした場合の既定の動作では、関数呼び出しのシリアル化された入力および出力のバイト数が記録されます。 この動作により、ログが肥大化することも、機密情報が誤って公開されることもなく、入力および出力に関する最小限の情報が示されます。 このプロパティを true に設定すると、既定の関数ログ記録によって、関数の入力および出力の内容全体がログに記録されます。
logReplayEvents false オーケストレーションの再生イベントを Application Insights に書き込むかどうかを示す値。
eventGridTopicEndpoint Azure Event Grid カスタム トピック エンドポイントの URL。 このプロパティが設定されている場合は、オーケストレーションのライフ サイクル通知イベントがこのエンドポイントに発行されます。 このプロパティは、アプリ設定の解決をサポートします。
eventGridKeySettingName EventGridTopicEndpoint での Azure Event Grid カスタム トピックによる認証に使用されるキーを含むアプリ設定の名前。
eventGridPublishRetryCount 0 Event Grid トピックへの発行が失敗した場合に再試行する回数。
eventGridPublishRetryInterval 5 分 Event Grid の発行を再試行する間隔 (hh:mm:ss 形式)。
eventGridPublishEventTypes Event Grid に発行するイベントの種類の一覧。 指定されていない場合は、すべてのイベントの種類が発行されます。 指定できる値は、StartedCompletedFailedTerminated です。
useAppLease true true に設定すると、アプリはタスク ハブ メッセージを処理する前にアプリレベルの BLOB リースを取得する必要があります。 詳細については、ディザスター リカバリーと geo ディストリビューションに関するドキュメントを参照してください。 v2.3.0 以降で利用可能です。
useLegacyPartitionManagement false false に設定した場合は、スケールアウト時に関数の実行が重複する可能性を抑えるパーティション管理アルゴリズムを使用します。v2.3.0 以降で利用可能です。
useGracefulShutdown false (プレビュー) 正常なシャットダウンを有効にして、ホストのシャットダウンでインプロセス関数の実行が失敗する可能性を減らします。

これらの設定の多くはパフォーマンスの最適化を目的としています。 詳細については、「パフォーマンスと拡張性」を参照してください。

次のステップ