Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Buat aplikasi stateful dengan Durable Functions. Ini adalah ekstensi Azure Functions. Gunakan fungsi orchestrator untuk mengoordinasikan Durable Functions lain di aplikasi fungsi Anda. Fungsi orkestrator bersifat stateful, andal, serta dirancang untuk berjalan dalam waktu yang lama.
Bangun alur kerja yang stateful dan toleran terhadap kesalahan dengan Durable Task SDK di .NET, Python, dan Java. Gunakan orkestrator untuk mengoordinasikan aktivitas dan sub-orkestrasi. Orkestrator bersifat memiliki keadaan, andal, dan dibangun untuk berjalan dalam jangka waktu yang lama.
Batasan kode pengendali
Fungsi orkestrator menggunakan sumber peristiwa untuk memastikan eksekusi yang andal dan untuk mempertahankan status variabel lokal. Perilaku pemutaran ulang kode orkestrator membuat batasan pada jenis kode yang dapat Anda tulis dalam fungsi orkestrator. Misalnya, fungsi orkestrator harus deterministik: fungsi orkestrator diputar ulang beberapa kali, dan harus menghasilkan hasil yang sama setiap kali.
Orkestrator menggunakan sumber peristiwa untuk memastikan eksekusi yang andal dan untuk mempertahankan status variabel lokal. Perilaku pemutaran ulang kode orkestrator membuat batasan pada jenis kode yang dapat Anda tulis di orkestrator. Misalnya, orkestrator harus deterministik: orkestrator memutar ulang beberapa kali, dan harus menghasilkan hasil yang sama setiap kali.
Menggunakan API deterministik
Berikut adalah beberapa panduan sederhana untuk membantu memastikan kode Anda deterministik.
Panggil API dari bahasa target Anda dalam fungsi orkestrator, tetapi hanya gunakan API deterministik. API deterministik selalu mengembalikan nilai yang sama untuk input yang sama, tidak peduli kapan atau seberapa sering itu dipanggil.
Bagian berikut memberikan panduan tentang API dan pola yang harus Anda hindari karena tidak deterministik. Pembatasan ini hanya berlaku untuk fungsi orkestrator. Jenis fungsi lain tidak memiliki batasan tersebut.
Berikut adalah beberapa panduan sederhana untuk membantu memastikan kode Anda deterministik.
Panggil API dari bahasa target Anda di orkestrator, tetapi hanya gunakan API deterministik. API deterministik selalu mengembalikan nilai yang sama untuk input yang sama, tidak peduli kapan atau seberapa sering itu dipanggil.
Bagian berikut memberikan panduan tentang API dan pola yang harus Anda hindari karena tidak deterministik. Pembatasan ini hanya berlaku untuk orkestrator. Aktivitas tidak memiliki batasan seperti itu.
Nota
Artikel ini membahas batasan kode orkestrator umum, tetapi tidak komprehensif. Fokus pada apakah API deterministik. Dengan pola pikir tersebut, Anda biasanya dapat mengetahui API mana yang aman digunakan tanpa merujuk ke daftar ini.
Tanggal dan waktu
API berbasis waktu bersifat nondeterministik dan tidak boleh digunakan dalam fungsi orkestrator. Setiap pemutaran ulang fungsi orkestrator menghasilkan nilai yang berbeda. Sebagai gantinya, gunakan API yang setara Durable Functions untuk mendapatkan tanggal atau waktu saat ini, yang tetap konsisten di seluruh pemutaran ulang.
Jangan gunakan DateTime.Now, DateTime.UtcNow, atau API setara untuk mendapatkan waktu saat ini. Kelas seperti Stopwatch juga harus dihindari. Dalam fungsi orkestrator in-process .NET, gunakan properti IDurableOrchestrationContext.CurrentUtcDateTime untuk mendapatkan waktu saat ini. Untuk fungsi orkestrator terisolasi .NET, gunakan properti TaskOrchestrationContext.CurrentDateTimeUtc untuk mendapatkan waktu saat ini.
DateTime startTime = context.CurrentUtcDateTime;
// do some work
TimeSpan totalTime = context.CurrentUtcDateTime.Subtract(startTime);
API berbasis waktu bersifat nondeterministik dan tidak boleh digunakan dalam orkestrator. Setiap pemutaran ulang orkestrator menghasilkan nilai yang berbeda. Sebagai gantinya, gunakan API setara Durable Task SDK untuk mendapatkan tanggal atau waktu saat ini, yang tetap konsisten di seluruh pemutaran ulang.
Jangan gunakan DateTime.Now, DateTime.UtcNow, atau API setara untuk mendapatkan waktu saat ini. Kelas seperti Stopwatch juga harus dihindari.
TaskOrchestrationContext.CurrentUtcDateTime Gunakan properti untuk mendapatkan waktu saat ini.
using Microsoft.DurableTask;
public class TimerExample : TaskOrchestrator<object?, TimeSpan>
{
public override async Task<TimeSpan> RunAsync(TaskOrchestrationContext context, object? input)
{
// Use context.CurrentUtcDateTime instead of DateTime.Now or DateTime.UtcNow
DateTime startTime = context.CurrentUtcDateTime;
// do some work
await context.CallActivityAsync("DoWork", null);
TimeSpan totalTime = context.CurrentUtcDateTime.Subtract(startTime);
return totalTime;
}
}
GUID (Globally Unique Identifier) dan UUID (Universally Unique Identifier)
API yang mengembalikan GUID atau UUID acak bersifat nondeterministik karena nilai yang dihasilkan berbeda untuk setiap pemutaran ulang. Bergantung pada bahasa Anda, API bawaan untuk menghasilkan GUID atau UUID deterministik mungkin tersedia. Jika tidak, gunakan fungsi aktivitas untuk mengembalikan GUID atau UUID yang dihasilkan secara acak.
Alih-alih API seperti Guid.NewGuid(), gunakan API objek NewGuid() konteks untuk menghasilkan GUID acak yang aman untuk pemutaran ulang orkestrator.
Guid randomGuid = context.NewGuid();
Nota
GUID yang dihasilkan dengan API konteks orkestrasi adalah UUID Tipe 5.
API yang mengembalikan GUID atau UUID acak bersifat nondeterministik karena nilai yang dihasilkan berbeda untuk setiap pemutaran ulang. Bergantung pada bahasa Anda, API bawaan untuk menghasilkan GUID atau UUID deterministik mungkin tersedia. Jika tidak, gunakan aktivitas untuk mengembalikan GUID atau UUID yang dihasilkan secara acak.
Alih-alih API seperti Guid.NewGuid(), gunakan API objek NewGuid() konteks untuk menghasilkan GUID acak yang aman untuk pemutaran ulang orkestrator.
using Microsoft.DurableTask;
public class GuidExample : TaskOrchestrator<object?, Guid>
{
public override async Task<Guid> RunAsync(TaskOrchestrationContext context, object? input)
{
// Use context.NewGuid() instead of Guid.NewGuid()
Guid randomGuid = context.NewGuid();
return randomGuid;
}
}
Nota
GUID yang dihasilkan dengan API konteks orkestrasi adalah UUID Tipe 5.
Angka acak
Gunakan fungsi aktivitas untuk mengembalikan angka acak ke fungsi orkestrator. Nilai pengembalian fungsi aktivitas selalu aman untuk diputar ulang karena disimpan ke dalam riwayat orkestrasi.
Atau, Anda dapat menggunakan generator angka acak dengan nilai benih tetap langsung dalam fungsi orkestrator. Pendekatan ini aman selama urutan angka yang sama dihasilkan untuk setiap pemutaran ulang orkestrasi.
Gunakan aktivitas untuk mengembalikan angka acak ke orkestrator. Nilai pengembalian aktivitas selalu aman untuk diputar ulang karena disimpan ke dalam riwayat orkestrasi.
Atau, Anda dapat menggunakan generator angka acak dengan nilai benih tetap langsung di orkestrator. Pendekatan ini aman selama urutan angka yang sama dihasilkan untuk setiap pemutaran ulang orkestrasi.
Pengikat
Jangan gunakan pengikatan dalam fungsi orkestrator, termasuk pengikatan klien orkestrasi dan klien entitas . Gunakan pengikatan input dan output hanya dalam fungsi klien atau aktivitas. Fungsi orkestrator dapat diputar ulang beberapa kali, menyebabkan I/O nondeterministik dan duplikat dengan sistem eksternal.
Orkestrator tidak boleh melakukan operasi I/O langsung dengan sistem eksternal. Pindahkan operasi I/O ke aktivitas. Orkestrator dapat memutar ulang beberapa kali, menyebabkan I/O nondeterministik dan duplikat dengan sistem eksternal.
Variabel statis
Variabel statis dapat berubah dari waktu ke waktu, membuatnya tidak aman untuk fungsi orkestrator. Hindari menggunakan variabel statis dalam fungsi orkestrator karena nilainya dapat berubah dari waktu ke waktu, yang mengakibatkan perilaku runtime nondeterministik. Sebagai gantinya, gunakan konstanta, atau batasi penggunaan variabel statis ke fungsi aktivitas.
Variabel statis dapat berubah dari waktu ke waktu, membuatnya tidak aman untuk orkestrator. Hindari menggunakan variabel statis di orkestrator karena nilainya dapat berubah dari waktu ke waktu, yang mengakibatkan perilaku runtime nondeterministik. Sebagai gantinya, gunakan konstanta, atau batasi penggunaan variabel statis untuk aktivitas.
Nota
Bahkan di luar fungsi orkestrator, menggunakan variabel statis dalam Azure Functions dapat bermasalah karena berbagai alasan karena tidak ada jaminan bahwa status statis bertahan di beberapa eksekusi fungsi. Hindari variabel statis kecuali dalam kasus penggunaan tertentu, seperti strategi penyimpanan sementara dalam memori terbaik pada fungsi aktivitas atau entitas.
Variabel lingkungan
Variabel lingkungan dalam fungsi orkestrator dapat berubah dari waktu ke waktu, menghasilkan perilaku runtime nondeterministik. Jika fungsi orkestrator memerlukan konfigurasi yang ditentukan dalam variabel lingkungan, Anda harus meneruskan nilai konfigurasi ke fungsi orkestrator sebagai input atau sebagai nilai pengembalian fungsi aktivitas.
Variabel lingkungan pada orkestrator dapat berubah dari waktu ke waktu, yang menghasilkan perilaku runtime yang tidak deterministik. Jika orkestrator memerlukan konfigurasi yang ditentukan dalam variabel lingkungan, Anda harus meneruskan nilai konfigurasi ke orkestrator sebagai input atau sebagai nilai pengembalian aktivitas.
Jaringan dan HTTP
Gunakan fungsi aktivitas untuk melakukan panggilan jaringan keluar. Jika Anda perlu melakukan panggilan HTTP dari fungsi orkestrator Anda, Anda juga dapat menggunakan API HTTP yang tahan lama.
Gunakan aktivitas untuk melakukan panggilan jaringan keluar. Orkestrator tidak boleh melakukan panggilan HTTP langsung atau permintaan jaringan lainnya karena operasi ini tidak mendeterministik.
API yang memblokir utas
Memblokir API seperti sleep dapat menyebabkan masalah performa dan skala untuk fungsi orkestrator dan dapat mengakibatkan biaya waktu eksekusi yang tidak perlu dalam paket Konsumsi Azure Functions. Gunakan alternatif saat tersedia. Misalnya, gunakan timer Durable untuk membuat penundaan yang aman untuk pemutaran ulang dan tidak dihitung terhadap waktu eksekusi orkestrator.
Memblokir API seperti "tidur" dapat menyebabkan masalah performa dan skala untuk orkestrator dan harus dihindari. Gunakan timer tahan lama untuk membuat penundaan yang aman untuk pemutaran ulang.
Gunakan context.CreateTimer() alih-alih Task.Delay() atau Thread.Sleep().
// Don't use Task.Delay() or Thread.Sleep()
// Use context.CreateTimer() instead
await context.CreateTimer(context.CurrentUtcDateTime.AddMinutes(5), CancellationToken.None);
API Asinkron
Kode orkestrator tidak boleh memulai operasi asinkron apa pun, kecuali operasi yang ditentukan oleh objek konteks pemicu orkestrasi. Misalnya, jangan pernah menggunakan Task.Run, Task.Delay, dan HttpClient.SendAsync di .NET atau setTimeout dan setInterval di JavaScript. Fungsi orkestrator hanya boleh menjadwalkan pekerjaan asinkron menggunakan Durable SDK API, seperti menjadwalkan fungsi aktivitas. Jenis pemanggilan asinkron lainnya harus dilakukan di dalam fungsi aktivitas.
Kode orkestrator tidak boleh memulai operasi asinkron apa pun, kecuali operasi yang ditentukan oleh objek konteks orkestrasi. Misalnya, jangan pernah menggunakan Task.Run, Task.Delay, dan HttpClient.SendAsync di .NET. Orkestrator hanya boleh menjadwalkan pekerjaan asinkron menggunakan Durable Task SDK API, seperti aktivitas penjadwalan. Jenis pemanggilan asinkron lainnya harus dilakukan di dalam aktivitas.
Fungsi JavaScript Asinkron
Deklarasikan fungsi orkestrator JavaScript sebagai fungsi generator sinkron. Jangan mendeklarasikan fungsi orkestrator JavaScript seperti async karena runtime Node.js tidak menjamin perilaku deterministik untuk async fungsi.
Koroutin Python
Jangan mendeklarasikan fungsi orkestrator Python sebagai koroutin. Jangan gunakan kata kunci async karena semantik coroutine tidak selaras dengan model pemutaran ulang Durable Functions. Deklarasikan fungsi orkestrator Python sebagai generator, dan gunakan yield alih-alih await dengan API context.
Anda tidak boleh mendeklarasikan orkestrator Python sebagai fungsi koroutine. Dengan kata lain, jangan pernah mendeklarasikan orkestrator Python dengan kata kunci async karena semantik coroutine tidak selaras dengan model pemutaran ulang Durable Task. Anda harus selalu mendeklarasikan orkestrator Python sebagai generator, yang berarti Anda harus menggunakan yield alih-alih await saat memanggil API konteks.
from durabletask import task
# CORRECT - use yield (generator function)
def my_orchestrator(ctx: task.OrchestrationContext, input: str):
result = yield ctx.call_activity(my_activity, input=input)
return result
# WRONG - don't use async/await
async def bad_orchestrator(ctx: task.OrchestrationContext, input: str):
result = await ctx.call_activity(my_activity, input=input) # This won't work!
return result
API utas .NET
Kerangka Kerja Tugas Tahan Lama menjalankan kode orkestrator pada satu utas dan tidak dapat berinteraksi dengan utas lain. Menjalankan kelanjutan asinkron pada utas kumpulan pekerja dalam eksekusi orkestrasi dapat mengakibatkan eksekusi atau kebuntuan nondeterministik. Untuk alasan ini, fungsi orkestrator Anda seharusnya hampir tidak pernah menggunakan API threading. Misalnya, jangan pernah gunakan ConfigureAwait(continueOnCapturedContext: false) dalam fungsi orkestrator untuk memastikan kelanjutan tugas berjalan pada fungsi orkestrator asli SynchronizationContext.
Nota
Kerangka Kerja Tugas Tahan Lama mencoba mendeteksi penggunaan utas nonorkestrator yang tidak disengaja dalam fungsi orkestrator. Jika menemukan pelanggaran, kerangka kerja melempar pengecualian NonDeterministicOrchestrationException . Namun, perilaku deteksi ini tidak akan menangkap semua pelanggaran, dan Anda tidak boleh bergantung padanya.
Kerangka Kerja Tugas Tahan Lama menjalankan kode orkestrator pada satu utas dan tidak dapat berinteraksi dengan utas lain. Menjalankan kelanjutan asinkron pada utas kumpulan pekerja dalam eksekusi orkestrasi dapat mengakibatkan eksekusi atau kebuntuan nondeterministik. Untuk alasan ini, orkestrator Anda sebaiknya hampir tidak pernah menggunakan API threading. Misalnya, jangan pernah gunakan ConfigureAwait(continueOnCapturedContext: false) dalam orkestrator untuk memastikan kelanjutan proses berjalan pada SynchronizationContext orkestrator awal.
Nota
Framework Durable Task berupaya mendeteksi penggunaan utas non-orkestrator secara tidak sengaja di orkestrator. Jika menemukan pelanggaran, kerangka kerja melempar pengecualian NonDeterministicOrchestrationException . Namun, perilaku deteksi ini tidak akan menangkap semua pelanggaran, dan Anda tidak boleh bergantung padanya.
Pembuatan Versi
Orkestrasi tahan lama dapat berjalan selama hari, bulan, tahun, atau bahkan sebagai orkestrasi kekal. Perubahan kode yang memengaruhi orkestrasi yang sedang berjalan dapat memutus perilaku pemutaran ulang, jadi rencanakan dengan cermat sebelum Anda memperbarui aplikasi. Untuk informasi selengkapnya, lihat Penerapan versi.
Orkestrasi tahan lama dapat berjalan selama bertahun-hari, berbulan-bulan, bertahun-tahun, atau bahkan tanpa batas waktu. Perubahan kode yang memengaruhi orkestrasi yang sedang berjalan dapat memutus perilaku pemutaran ulang, jadi rencanakan dengan cermat sebelum Anda memperbarui aplikasi. Strategi penerapan versi umum mencakup penyebaran berdampingan dan menggunakan nama hub tugas khusus versi.
Tugas tahan lama
Nota
Bagian ini menjelaskan detail implementasi internal Kerangka Kerja Tugas Tahan Lama. Anda tidak perlu mengetahui informasi ini untuk menggunakan Durable Functions, tetapi membantu menjelaskan perilaku pemutaran ulang.
Tugas yang dapat menunggu dengan aman dalam fungsi orkestrator terkadang disebut tugas tahan lama. Kerangka Kerja Tugas Tahan Lama membuat dan mengelola tugas-tugas ini. Contohnya termasuk tugas yang dikembalikan oleh CallActivityAsync, WaitForExternalEvent, dan CreateTimer dalam fungsi orkestrator .NET.
Daftar objek TaskCompletionSource di .NET mengelola tugas tahan lama ini secara internal. Selama pemutaran ulang, kode orkestrator membuat tugas-tugas ini. Dispatcher menyelesaikannya saat mendaftar peristiwa riwayat yang berkaitan.
Runtime menjalankan tugas secara sinkron pada satu utas hingga memutar ulang riwayat. Jika tugas tahan lama tidak selesai pada akhir pemutaran ulang riwayat, runtime mengambil tindakan yang sesuai. Misalnya, runtime dapat mengantrekan pesan untuk memanggil fungsi aktivitas.
Perilaku runtime ini menjelaskan mengapa fungsi orkestrator Anda tidak dapat menggunakan await atau yield dalam tugas yang tidak tahan lama. Thread dispatcher tidak dapat menunggu tugas selesai, dan panggilan balik yang berasal dari tugas tersebut dapat merusak status pelacakan fungsi orchestrator. Waktu proses mencakup pemeriksaan untuk membantu mendeteksi pelanggaran ini.
Untuk mempelajari selengkapnya tentang bagaimana Kerangka Tugas Durable menjalankan fungsi orkestrator, lihat kode sumber Durable Task di GitHub. Secara khusus, lihat TaskOrchestrationExecutor.cs dan TaskOrchestrationContext.cs.
Tugas yang dapat menunggu dengan aman di orkestrator terkadang disebut tugas tahan lama. Kerangka Kerja Tugas Tahan Lama membuat dan mengelola tugas-tugas ini. Contohnya termasuk tugas yang dikembalikan oleh CallActivityAsync, WaitForExternalEvent, dan CreateTimer di orkestrator .NET.
Daftar objek TaskCompletionSource di .NET mengelola tugas tahan lama ini secara internal. Selama pemutaran ulang, kode orkestrator membuat tugas-tugas ini. Dispatcher menyelesaikannya saat mendaftar peristiwa riwayat yang berkaitan.
Runtime menjalankan tugas secara sinkron pada satu utas hingga memutar ulang riwayat. Jika tugas tahan lama tidak selesai pada akhir pemutaran ulang riwayat, runtime mengambil tindakan yang sesuai. Misalnya, runtime dapat mengantrekan pesan untuk memanggil aktivitas.
Perilaku runtime ini menjelaskan mengapa orkestrator Anda tidak dapat menggunakan await atau yield dalam tugas yang tidak tahan lama. Thread dispatcher tidak bisa menunggu hingga tugas selesai, dan callback yang dihasilkan oleh tugas tersebut dapat merusak keadaan pelacakan orkestrator. Waktu proses mencakup pemeriksaan untuk membantu mendeteksi pelanggaran ini.
Untuk mempelajari selengkapnya tentang cara Kerangka Tugas Tahan Lama menjalankan orkestrator, lihat kode sumber Kerangka Tugas Tahan Lama pada GitHub. Secara khusus, lihat TaskOrchestrationExecutor.cs dan TaskOrchestrationContext.cs.