Durable Task のシングルトン オーケストレーター

バックグラウンド ジョブでは、多くの場合、特定のオーケストレーターのインスタンスが一度に 1 つだけ実行され、重複するオーケストレーションが同時に実行されないようにする必要があります。 このシングルトン パターンを Durable Functions または Durable Task SDK で実装するには、オーケストレーターの作成時に特定のインスタンス ID を割り当て、その ID を持つインスタンスが既に実行されているかどうかを確認してから、新しいインスタンスを開始します。

この記事では、サポートされている各言語のコード例を使用してシングルトン オーケストレーターを実装する方法について説明します。

[前提条件]

シングルトン パターンには潜在的な競合状態があります。 2 つのクライアントがチェックアンドスタート ロジックを同時に実行すると、両方の呼び出しで成功が報告される可能性がありますが、実際に開始されるのはオーケストレーション インスタンスが 1 つだけです。 要件によっては、望ましくない副作用が発生する可能性があります。 厳密な単一インスタンスの保証が必要な場合は、ロック メカニズムを追加することを検討してください。

Important

現在、PowerShell Durable Task SDK は使用できません。

シングルトン オーケストレーターの例

次の例は、シングルトン バックグラウンド ジョブ オーケストレーションを作成する HTTP トリガー関数を示しています。 このコードは、指定されたインスタンス ID に対してアクティブなインスタンスが 1 つだけ存在することを確認しようとします。

[Function("HttpStartSingle")]
public static async Task<HttpResponseData> RunSingle(
    [HttpTrigger(AuthorizationLevel.Function, "post", Route = "orchestrators/{functionName}/{instanceId}")] HttpRequestData req,
    [DurableClient] DurableTaskClient starter,
    string functionName,
    string instanceId,
    FunctionContext executionContext)
{
    ILogger logger = executionContext.GetLogger("HttpStartSingle");

    // Check if an instance with the specified ID already exists or an existing one stopped running(completed/failed/terminated).
    OrchestrationMetadata? existingInstance = await starter.GetInstanceAsync(instanceId, getInputsAndOutputs: false);
    if (existingInstance == null 
    || existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Completed 
    || existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Failed 
    || existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Terminated)
    {
        // An instance with the specified ID doesn't exist or an existing one stopped running, create one.
        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        await starter.ScheduleNewOrchestrationInstanceAsync(functionName, requestBody, new StartOrchestrationOptions { InstanceId = instanceId });
        logger.LogInformation($"Started orchestration with ID = '{instanceId}'.");
        return await starter.CreateCheckStatusResponseAsync(req, instanceId);
    }
    else
    {
        // An instance with the specified ID exists or an existing one still running, don't create one.
        var response = req.CreateResponse(HttpStatusCode.Conflict);
        await response.WriteStringAsync($"An instance with ID '{instanceId}' already exists.");
        return response;
    }
}

前の C# コードは、分離されたワーカー モデル用です。これは、.NET アプリに推奨されるモデルです。 インプロセス ワーカーモデルと分離ワーカーモデルの違いの詳細については、Durable Functions バージョンに関する記事を参照してください。

次の例は、Durable Task SDK を使用してシングルトン オーケストレーションを作成する方法を示しています。 このコードは、指定されたインスタンス ID に対してアクティブなインスタンスが 1 つだけ存在することを確認しようとします。

using Microsoft.DurableTask.Client;

// Check if an instance with the specified ID already exists
string instanceId = "singleton-job";
OrchestrationMetadata? existingInstance = await client.GetInstanceAsync(instanceId, getInputsAndOutputs: false);

if (existingInstance == null ||
    existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Completed ||
    existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Failed ||
    existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Terminated)
{
    // An instance with the specified ID doesn't exist or an existing one stopped running, create one.
    await client.ScheduleNewOrchestrationInstanceAsync("MyOrchestration", input, new StartOrchestrationOptions(instanceId));
    Console.WriteLine($"Started orchestration with ID = '{instanceId}'.");
}
else
{
    // An instance with the specified ID exists or an existing one still running.
    Console.WriteLine($"An instance with ID '{instanceId}' already exists.");
}

シングルトン パターンのしくみ

インスタンス ID はタスク ハブ内で一意であるため、既知の固定 ID を使用してオーケストレーションをスケジュールし、その状態を確認すると、最初に重複する同時実行が防止されます。 既定では、インスタンス ID はランダムに生成される GUID です。 ただし、前の例では、特定のインスタンス ID が渡されます。 その後、コードはオーケストレーション インスタンスのメタデータをフェッチして、その ID を持つインスタンスが既に実行されているかどうかを確認します。 そのようなインスタンスが実行されていない場合は、その ID で新しいインスタンスが作成されます。

オーケストレーター関数自体は、任意のパターン (開始および完了する標準関数、または継続的に実行される 永続的オーケストレーション ) を使用できます。 シングルトン パターンは、同時に実行されるインスタンスの数のみを制御します。

次のステップ