Bagikan melalui


Menangani kesalahan dalam Durable Functions (Azure Functions)

Orkestrasi Durable Functions diimplementasikan dalam kode dan dapat menggunakan fitur penanganan kesalahan bawaan bahasa pemrograman. Benar-benar tidak ada konsep baru yang perlu Anda pelajari untuk menambahkan penanganan kesalahan dan kompensasi ke dalam orkestrasi Anda. Namun, ada beberapa perilaku yang harus Anda waspadai.

Catatan

Model pemrograman Node.js versi 4 untuk Azure Functions umumnya tersedia. Model v4 baru dirancang untuk memiliki pengalaman yang lebih fleksibel dan intuitif untuk pengembang JavaScript dan TypeScript. Pelajari selengkapnya tentang perbedaan antara v3 dan v4 dalam panduan migrasi.

Dalam cuplikan kode berikut, JavaScript (PM4) menunjukkan model pemrograman V4, pengalaman baru.

Kesalahan dalam fungsi aktivitas

Setiap pengecualian yang dilemparkan dalam fungsi aktivitas di marshaled kembali ke fungsi orkestrator dan dilemparkan sebagai FunctionFailedException. Anda dapat menulis penanganan kesalahan dan kode kompensasi yang sesuai dengan kebutuhan Anda dalam fungsi orkestrator.

Misalnya, pertimbangkan fungsi orkestrator berikut yang mentransfer dana dari satu akun ke akun lainnya:

[FunctionName("TransferFunds")]
public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var transferDetails = context.GetInput<TransferOperation>();

    await context.CallActivityAsync("DebitAccount",
        new
        {
            Account = transferDetails.SourceAccount,
            Amount = transferDetails.Amount
        });

    try
    {
        await context.CallActivityAsync("CreditAccount",
            new
            {
                Account = transferDetails.DestinationAccount,
                Amount = transferDetails.Amount
            });
    }
    catch (Exception)
    {
        // Refund the source account.
        // Another try/catch could be used here based on the needs of the application.
        await context.CallActivityAsync("CreditAccount",
            new
            {
                Account = transferDetails.SourceAccount,
                Amount = transferDetails.Amount
            });
    }
}

Catatan

Contoh C# sebelumnya adalah untuk Durable Functions 2.x. Untuk Durable Functions 1.x, Anda harus menggunakan DurableOrchestrationContext dan bukan IDurableOrchestrationContext. Untuk informasi selengkapnya tentang perbedaan antara versi, lihat artikel Versi Durable Functions.

Jika panggilan fungsi CreditAccount pertama gagal, fungsi orkestrator mengkompensasi dengan memberi kredit dana kembali ke akun sumber.

Percobaan otomatis saat kegagalan

Saat Anda memanggil fungsi aktivitas atau fungsi sub-orkestrasi, Anda dapat menentukan kebijakan percobaan kembali otomatis. Contoh berikut mencoba memanggil fungsi hingga tiga kali dan menunggu 5 detik di antara setiap percobaan:

[FunctionName("TimerOrchestratorWithRetry")]
public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var retryOptions = new RetryOptions(
        firstRetryInterval: TimeSpan.FromSeconds(5),
        maxNumberOfAttempts: 3);

    await context.CallActivityWithRetryAsync("FlakyFunction", retryOptions, null);

    // ...
}

Catatan

Contoh C# sebelumnya adalah untuk Durable Functions 2.x. Untuk Durable Functions 1.x, Anda harus menggunakan DurableOrchestrationContext dan bukan IDurableOrchestrationContext. Untuk informasi selengkapnya tentang perbedaan antara versi, lihat artikel Versi Durable Functions.

Panggilan fungsi aktivitas dalam contoh sebelumnya mengambil parameter untuk mengonfigurasi kebijakan percobaan kembali otomatis. Ada beberapa opsi untuk menyesuaikan kebijakan percobaan kembali otomatis:

  • Max number of attempts: Jumlah maksimal dari upaya yang dicoba. Jika diatur ke 1, tidak akan ada percobaan ulang.
  • Interval percobaan pertama: Jumlah waktu untuk menunggu sebelum upaya coba lagi pertama.
  • Koefisien backoff: Koefisien yang digunakan untuk menentukan tingkat peningkatan backoff. Default ke 1.
  • Interval percobaan maksimal: Jumlah waktu maksimum untuk menunggu di antara upaya coba lagi.
  • Coba lagi waktu habis: Jumlah maksimum waktu yang harus dihabiskan untuk melakukan pengulangan. Perilaku default adalah mencoba kembali tanpa batas waktu.

Penangan coba lagi kustom

Saat menggunakan .NET atau Java, Anda juga memiliki opsi untuk menerapkan penangan coba lagi dalam kode. Ini berguna ketika kebijakan percobaan ulang deklaratif tidak cukup ekspresif. Untuk bahasa yang tidak mendukung penangan percobaan ulang kustom, Anda masih memiliki opsi untuk menerapkan kebijakan percobaan ulang menggunakan perulangan, penanganan pengecualian, dan pengatur waktu untuk memasukkan penundaan antara percobaan ulang.

RetryOptions retryOptions = new RetryOptions(
    firstRetryInterval: TimeSpan.FromSeconds(5),
    maxNumberOfAttempts: int.MaxValue)
    {
        Handle = exception =>
        {
            // True to handle and try again, false to not handle and throw.
            if (exception is TaskFailedException failure)
            {
                // Exceptions from TaskActivities are always this type. Inspect the
                // inner Exception to get more details.
            }

            return false;
        };
    }

await ctx.CallActivityWithRetryAsync("FlakeyActivity", retryOptions, null);

Batas waktu fungsi

Anda mungkin ingin meninggalkan panggilan fungsi dalam fungsi orkestrator jika terlalu lama untuk diselesaikan. Cara yang tepat untuk melakukannya hari ini adalah dengan membuat timer tahan lama dengan pemilih tugas "apa saja", seperti dalam contoh berikut:

[FunctionName("TimerOrchestrator")]
public static async Task<bool> Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    TimeSpan timeout = TimeSpan.FromSeconds(30);
    DateTime deadline = context.CurrentUtcDateTime.Add(timeout);

    using (var cts = new CancellationTokenSource())
    {
        Task activityTask = context.CallActivityAsync("FlakyFunction");
        Task timeoutTask = context.CreateTimer(deadline, cts.Token);

        Task winner = await Task.WhenAny(activityTask, timeoutTask);
        if (winner == activityTask)
        {
            // success case
            cts.Cancel();
            return true;
        }
        else
        {
            // timeout case
            return false;
        }
    }
}

Catatan

Contoh C# sebelumnya adalah untuk Durable Functions 2.x. Untuk Durable Functions 1.x, Anda harus menggunakan DurableOrchestrationContext dan bukan IDurableOrchestrationContext. Untuk informasi selengkapnya tentang perbedaan antara versi, lihat artikel Versi Durable Functions.

Catatan

Mekanisme ini sebenarnya tidak menghentikan eksekusi fungsi aktivitas yang sedang berlangsung. Sebaliknya, itu hanya memungkinkan fungsi orkestrator untuk mengabaikan hasil dan melanjutkan. Untuk informasi selengkapnya, lihat dokumentasi Timer.

Pengecualian yang tidak tertangani

Jika fungsi orkestrator gagal dengan pengecualian tidak tertangani, detail pengecualian dicatat dan instans selesai dengan Failed status.

Langkah berikutnya