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.
Fungsi orkestrator dapat memanggil fungsi orkestrator lain sebagai sub-orkestrasi. Sub-orkestrasi berjalan sebagai anak dari orkestrator panggilan (induk) dan berperilaku seperti aktivitas dari perspektif pemanggil: dapat mengembalikan nilai, melemparkan pengecualian yang ditangkap oleh induk, dan mendukung coba lagi otomatis.
Kapan menggunakan sub-orkestrasi
Gunakan sub-orkestrasi saat Anda perlu:
- Buat blok penyusun alur kerja yang dapat digunakan kembali: Ekstrak alur kerja multi-langkah ke orkestratornya sendiri sehingga beberapa orkestrasi induk dapat memanggilnya.
- Fan out orkestrasi secara paralel: Jadwalkan banyak instans orkestrator yang sama sekaligus dan tunggu hingga semuanya selesai.
- Atur alur kerja yang kompleks: Pecahkan orkestrasi besar menjadi potongan bernama yang dapat diuji alih-alih satu fungsi panjang.
Nota
Sub-orkestrasi harus didefinisikan dalam aplikasi yang sama dengan orkestrasi induk. Untuk memanggil orkestrasi di aplikasi lain, gunakan pola polling HTTP 202 sebagai gantinya. Untuk informasi selengkapnya, lihat Fitur HTTP.
Dalam artikel ini:
- Tentukan sub-orkestrasi — Contoh penyediaan perangkat tunggal
- Jalankan sub-orkestrasi secara paralel — Pola fan-out dengan ID instance yang bersifat deterministik
Nota
Di PowerShell, sub-orkestrasi hanya didukung di SDK mandiri: AzureFunctions.PowerShell.Durable.SDK. Untuk perbedaan antara SDK mandiri dan SDK bawaan warisan, lihat panduan migrasi.
Mendefinisikan sub-orkestrasi
Contoh berikut mengilustrasikan skenario IoT di mana beberapa perangkat perlu disiapkan. Fungsi ini mewakili alur kerja penyiapan yang berjalan untuk setiap perangkat:
Model pekerja terisolasi
public static async Task DeviceProvisioningOrchestration(
[OrchestrationTrigger] TaskOrchestrationContext context, string deviceId)
{
// Step 1: Create an installation package in blob storage and return a SAS URL.
Uri sasUrl = await context.CallActivityAsync<Uri>("CreateInstallationPackage", deviceId);
// Step 2: Notify the device that the installation package is ready.
await context.CallActivityAsync("SendPackageUrlToDevice", (deviceId, sasUrl));
// Step 3: Wait for the device to acknowledge that it has downloaded the new package.
await context.WaitForExternalEvent<bool>("DownloadCompletedAck");
// Step 4: ...
}
Model dalam proses
public static async Task DeviceProvisioningOrchestration(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
string deviceId = context.GetInput<string>();
// Step 1: Create an installation package in blob storage and return a SAS URL.
Uri sasUrl = await context.CallActivityAsync<Uri>("CreateInstallationPackage", deviceId);
// Step 2: Notify the device that the installation package is ready.
await context.CallActivityAsync("SendPackageUrlToDevice", Tuple.Create(deviceId, sasUrl));
// Step 3: Wait for the device to acknowledge that it has downloaded the new package.
await context.WaitForExternalEvent<bool>("DownloadCompletedAck");
// Step 4: ...
}
using Microsoft.DurableTask;
[DurableTask]
public class DeviceProvisioningOrchestration : TaskOrchestrator<string, object?>
{
public override async Task<object?> RunAsync(TaskOrchestrationContext context, string deviceId)
{
// Step 1: Create an installation package in blob storage and return a SAS URL.
Uri sasUrl = await context.CallActivityAsync<Uri>("CreateInstallationPackage", deviceId);
// Step 2: Notify the device that the installation package is ready.
await context.CallActivityAsync("SendPackageUrlToDevice", (deviceId, sasUrl.ToString()));
// Step 3: Wait for the device to acknowledge that it has downloaded the new package.
await context.WaitForExternalEvent<bool>("DownloadCompletedAck");
// Step 4: ...
return null;
}
}
Fungsi orkestrator ini dapat berjalan mandiri untuk penyiapan perangkat satu kali, atau orkestrator induk dapat menjadwalkannya sebagai sub-orkestrasi menggunakan API call-sub-orchestrator .
Menjalankan sub-orkestrasi secara paralel
Contoh berikut menunjukkan orkestrator induk yang mencabangkan beberapa sub-orkestrasi secara paralel. Beberapa bahasa menggunakan ID instans anak deterministik (berasal dari ID instans induk ditambah indeks) untuk mencegah sub-orkestrasi duplikat pada pemutaran ulang.
Model pekerja terisolasi
[Function("ProvisionNewDevices")]
public static async Task ProvisionNewDevices(
[OrchestrationTrigger] TaskOrchestrationContext context)
{
string[] deviceIds = await context.CallActivityAsync<string[]>("GetNewDeviceIds");
// Run multiple device provisioning flows in parallel
var provisioningTasks = new List<Task>();
foreach (string deviceId in deviceIds)
{
Task provisionTask = context.CallSubOrchestratorAsync("DeviceProvisioningOrchestration", deviceId);
provisioningTasks.Add(provisionTask);
}
await Task.WhenAll(provisioningTasks);
// ...
}
Model dalam proses
[FunctionName("ProvisionNewDevices")]
public static async Task ProvisionNewDevices(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
string[] deviceIds = await context.CallActivityAsync<string[]>("GetNewDeviceIds");
// Run multiple device provisioning flows in parallel
var provisioningTasks = new List<Task>();
foreach (string deviceId in deviceIds)
{
Task provisionTask = context.CallSubOrchestratorAsync("DeviceProvisioningOrchestration", deviceId);
provisioningTasks.Add(provisionTask);
}
await Task.WhenAll(provisioningTasks);
// ...
}
Langkah berikutnya
using Microsoft.DurableTask;
[DurableTask]
public class ProvisionNewDevices : TaskOrchestrator<object?, object?>
{
public override async Task<object?> RunAsync(TaskOrchestrationContext context, object? input)
{
string[] deviceIds = await context.CallActivityAsync<string[]>("GetNewDeviceIds");
// Run multiple device provisioning flows in parallel
var provisioningTasks = new List<Task>();
foreach (string deviceId in deviceIds)
{
Task provisionTask = context.CallSubOrchestratorAsync("DeviceProvisioningOrchestration", deviceId);
provisioningTasks.Add(provisionTask);
}
await Task.WhenAll(provisioningTasks);
return null;
}
}