Dayanıklı Görevde Tekilli Orkestratörler

Arka plan işleri için genellikle aynı anda belirli bir düzenleyicinin yalnızca bir örneğinin çalıştığından emin olmanız ve yinelenen düzenlemelerin eşzamanlı olarak çalışmasını engellemeniz gerekir. Bu tekil deseni Dayanıklı İşlevler veya Durable Görev SDK'ları kullanarak bir düzenleyiciye oluştururken belirli bir örnek kimliği atayabilir ve yeni bir tane başlatmadan önce söz konusu kimliğe sahip bir örneğin zaten çalışıp çalışmadığını denetleyerek uygulayabilirsiniz.

Bu makalede, desteklenen her dil için kod örnekleriyle tekdüzen düzenleyicilerin nasıl uygulanacakları gösterilmektedir.

Prerequisites

Uyarı

Singleton deseninde olası bir yarış koşulu vardır. İki istemci aynı anda denetim ve başlatma mantığını yürütürse, her iki çağrı da başarılı olduğunu bildirebilir, ancak aslında yalnızca bir düzenleme örneği başlatılır. Gereksinimlerinize bağlı olarak, bunun istenmeyen yan etkileri olabilir. Katı tek örnekli garantiler gerekiyorsa, ek kilitleme mekanizmaları eklemeyi göz önünde bulundurun.

Önemli

Şu anda PowerShell Dayanıklı Görev SDK'sı kullanılamıyor.

Singleton orchestrator örneği

Aşağıdaki örnekte, tek bir arka plan işi düzenlemesi oluşturan bir HTTP tetikleyici işlevi gösterilmektedir. Kod, belirtilen örnek kimliği için yalnızca bir etkin örneğin mevcut olduğundan emin olmak için çalışır.

[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;
    }
}

Uyarı

Önceki C# kodu, .NET uygulamalar için önerilen model olan yalıtılmış çalışan modeline yöneliktir. İşlem içi ve yalıtılmış çalışan modelleri arasındaki farklar hakkında daha fazla bilgi için Dayanıklı İşlevler sürümleri makalesine bakın.

Aşağıdaki örnek, Dayanıklı Görev SDK'larını kullanarak bir tekil orkestrasyonun nasıl oluşturulacağını göstermektedir. Kod, belirtilen örnek kimliği için yalnızca bir etkin örneğin mevcut olduğundan emin olmak için çalışır.

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.");
}

Tekil desen nasıl çalışır?

Örnek kimlikleri bir görev hub'ı içinde benzersiz olduğundan, bilinen, sabit bir kimlikle bir orkestrasyon zamanlamak ve durumunu ilk olarak denetlemek, yinelenen çalıştırmaları önler. Varsayılan olarak örnek kimlikleri rastgele oluşturulmuş GUID'lerdir. Ancak önceki örneklerde belirli bir örnek kimliği geçirilmiştir. Kod daha sonra orkestrasyon örneği meta verilerini getirerek, bu kimliğe sahip bir örneğin çalışmakta olup olmadığını denetler. Böyle bir örnek çalışmıyorsa, bu kimlikle yeni bir örnek oluşturulur.

Orchestrator işlevinin kendisi herhangi bir düzeni (başlayan ve tamamlanan standart bir işlev veya sürekli çalışan bir Ebedi Düzenleme ) kullanabilir. Tekil desen yalnızca eşzamanlı olarak çalıştırılacak örnek sayısını denetler.

Sonraki Adımlar