Durable Task의 싱글톤 오케스트레이터

백그라운드 작업의 경우 특정 오케스트레이터의 인스턴스가 한 번에 하나만 실행되도록 하여 중복 오케스트레이션이 동시에 실행되지 않도록 해야 하는 경우가 많습니다. Durable Functions 또는 구성 가능한 작업 SDK에서 특정 인스턴스 ID를 오케스트레이터에 할당한 다음, 새 인스턴스를 시작하기 전에 해당 ID가 있는 인스턴스가 이미 실행 중인지 확인하여 이 싱글톤 패턴을 구현할 수 있습니다.

이 문서에서는 지원되는 각 언어에 대한 코드 예제를 사용하여 싱글톤 오케스트레이터를 구현하는 방법을 보여 줍니다.

필수 조건

메모

싱글톤 패턴에는 잠재적인 경합 상태가 있습니다. 두 클라이언트가 동시에 확인 및 시작 논리를 실행하는 경우 두 호출 모두 성공을 보고할 수 있지만 실제로는 하나의 오케스트레이션 인스턴스만 시작됩니다. 요구 사항에 따라 바람직하지 않은 부작용이 있을 수 있습니다. 엄격한 단일 인스턴스 보장이 필요한 경우 추가 잠금 메커니즘을 추가하는 것이 좋습니다.

중요합니다

현재 PowerShell 지속성 작업 SDK는 사용할 수 없습니다.

싱글톤 오케스트레이터 예제

다음 예제에서는 싱글톤 백그라운드 작업 오케스트레이션을 만드는 HTTP 트리거 함수를 보여줍니다. 이 코드는 지정된 인스턴스 ID에 대해 하나의 활성 인스턴스만 존재하는지 확인합니다.

[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 앱에 권장되는 격리된 작업자 모델에 대한 것입니다. in-process 모델과 격리된 작업자 모델 간의 차이점에 대한 자세한 내용은 Durable Functions 버전 문서를 참조하세요.

다음 예제에서는 지속성 작업 SDK를 사용하여 싱글톤 오케스트레이션을 만드는 방법을 보여 줍니다. 이 코드는 지정된 인스턴스 ID에 대해 하나의 활성 인스턴스만 존재하는지 확인합니다.

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를 사용하여 새 인스턴스가 만들어집니다.

오케스트레이터 함수 자체는 시작 및 완료되는 표준 함수 또는 지속적으로 실행되는 영구 오케스트레이션 과 같은 모든 패턴을 사용할 수 있습니다. 싱글톤 패턴은 동시에 실행되는 인스턴스 수만 제어합니다.

다음 단계