Orkestrator singleton dalam Tugas Tahan Lama

Untuk pekerjaan latar belakang, Anda sering kali perlu memastikan bahwa hanya satu instans orkestrator tertentu yang berjalan pada satu waktu, mencegah orkestrasi duplikat berjalan secara bersamaan. Anda dapat menerapkan pola singleton ini di Durable Functions atau SDK Tugas Durable dengan menetapkan ID instans tertentu ke orkestrator saat membuatnya, lalu memeriksa apakah instans dengan ID tersebut sudah berjalan sebelum memulai yang baru.

Artikel ini memperlihatkan cara mengimplementasikan orkestrator singleton dengan contoh kode untuk setiap bahasa yang didukung.

Prasyarat

Nota

Ada potensi kondisi perlombaan dalam pola singleton. Jika dua klien menjalankan logika periksa-dan-mulai secara bersamaan, kedua panggilan mungkin melaporkan keberhasilan, tetapi hanya satu instance orkestrasi yang benar-benar memulai. Tergantung pada kebutuhan Anda, ini mungkin memiliki efek samping yang tidak diinginkan. Jika jaminan instans tunggal yang ketat diperlukan, pertimbangkan untuk menambahkan mekanisme penguncian tambahan.

Penting

Saat ini, PowerShell Durable Task SDK tidak tersedia.

Contoh orkestrator singleton

Contoh berikut menunjukkan fungsi pemicu HTTP yang membuat orkestrasi pekerjaan latar belakang singleton. Kode mencoba memastikan bahwa hanya satu instans aktif yang ada untuk ID instans tertentu.

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

Nota

Kode C# sebelumnya adalah untuk model pekerja terisolasi, yang merupakan model yang direkomendasikan untuk aplikasi .NET. Untuk informasi selengkapnya tentang perbedaan antara model pekerja dalam proses dan terisolasi, lihat artikel versi Durable Functions.

Contoh berikut menunjukkan cara membuat orkestrasi singleton menggunakan Durable Task SDK. Kode mencoba memastikan bahwa hanya satu instans aktif yang ada untuk ID instans tertentu.

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

Cara kerja pola singleton

Karena ID instans bersifat unik dalam hub tugas, menjadwalkan orkestrasi dengan ID yang sudah diketahui dan tetap serta memeriksa statusnya terlebih dahulu dapat mencegah terjadinya duplikasi eksekusi yang bersamaan. Secara default, ID instans adalah GUID yang dihasilkan secara acak. Namun, dalam contoh sebelumnya, ID instans yang spesifik diteruskan. Kode kemudian mengambil metadata instans orkestrasi untuk memeriksa apakah instans dengan ID tersebut sudah berjalan. Jika tidak ada instans seperti itu yang berjalan, instans baru dibuat dengan ID tersebut.

Fungsi orkestrator itu sendiri dapat menggunakan pola apa pun - fungsi standar yang dimulai dan selesai, atau Orkestrasi Abadi yang berjalan terus menerus. Pola singleton hanya mengontrol berapa banyak instans yang berjalan bersamaan.

Langkah berikutnya