Dílčí orchestrace

Funkce orchestratoru můžou volat jiné funkce orchestrátoru jako dílčí orchestrace. Dílčí orchestrace se spouští jako podřízený orchestrátor volání (nadřazený) a chová se jako aktivita z pohledu volajícího: může vrátit hodnotu, vyvolat výjimky zachycené nadřazeným objektem a podporovat automatické opakování.

Kdy použít dílčí orchestrace

Pokud potřebujete, použijte dílčí orchestrace:

  • Vytváření opakovaně použitelných stavebních bloků pracovního postupu: Extrahujte vícekrokový pracovní postup do vlastního orchestrátoru, aby ho mohlo volat více nadřazených orchestrací.
  • Paralelní spuštění orchestrací: Naplánujte mnoho instancí stejných orchestrátorů současně a vyčkejte, než se všechny dokončí.
  • Uspořádání složitých pracovních postupů: Rozdělte velkou orchestraci na pojmenované testovatelné části místo jedné dlouhé funkce.

Poznámka:

Podřízené orchestrace musí být definovány ve stejné aplikaci jako nadřazená orchestrace. Pokud chcete volat orchestrace v jiné aplikaci, namísto toho použijte vzor dotazování HTTP 202. Další informace najdete v tématu Funkce HTTP.

V tomto článku:

Poznámka:

V PowerShellu se dílčí orchestrace podporují jenom v samostatné sadě SDK: AzureFunctions.PowerShell.Durable.SDK. Rozdíly mezi samostatnou sadou SDK a starší integrovanou sadou SDK najdete v průvodci migrací.

Definování dílčí orchestrace

Následující příklad znázorňuje scénář IoT, ve kterém je potřeba nastavit více zařízení. Funkce představuje pracovní postup nastavení, který se spouští pro každé zařízení:

Izolovaný model pracovního procesu
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 v probíhajícím procesu
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;
    }
}

Tato funkce orchestrátoru může běžet samostatně pro jednorázové nastavení zařízení, nebo ji může nadřazený orchestrátor naplánovat jako dílčí orchestraci pomocí API call-sub-orchestrator.

Paralelní spouštění dílčích orchestrací

Následující příklad ukazuje nadřazený orchestrátor, který paralelně rozvětvuje více pod-orchestrací. Některé jazyky používají deterministické ID podřízené instance (odvozené z ID instance nadřazeného objektu plus index), aby se zabránilo duplicitním dílčím orchestracím při opětovném přehrávání.

Izolovaný model pracovního procesu
[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 v probíhajícím procesu
[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);

    // ...
}

Další kroky

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

Další kroky