Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
As funções orquestradoras podem chamar outras funções orquestradoras como suborquestrações. Uma sub-orquestração é executada como um subprocesso do orquestrador de chamada (pai) e se comporta como uma atividade do ponto de vista do chamador: pode retornar um valor, lançar exceções capturadas pelo pai e oferecer suporte à repetição automática.
Quando usar sub-orquestrações
Use suborquestrações quando necessário:
- Criar blocos de construção de workflow reutilizáveis: Extraia um workflow multi-etapas para um orquestrador dedicado, permitindo que várias orquestrações principais possam chamá-lo.
- Abane orquestrações em paralelo: Agende muitas instâncias do mesmo orquestrador simultaneamente e aguarde até que todas elas sejam concluídas.
- Organizar fluxos de trabalho complexos: Divida um grande processo de orquestração em partes nomeadas e testáveis em vez de uma única função longa.
Observação
As sub-orquestrações devem ser definidas no mesmo aplicativo que a orquestração pai. Para chamar orquestrações em um aplicativo diferente, use o padrão de sondagem HTTP 202. Para obter mais informações, consulte os recursos HTTP.
Neste artigo:
- Definir uma sub-orquestração — exemplo de provisionamento de dispositivo único
- Executar sub-orquestrações em paralelo — padrão de fan-out com IDs de instância determinísticos
Observação
No PowerShell, as sub-orquestrações têm suporte apenas no SDK autônomo: AzureFunctions.PowerShell.Durable.SDK. Para obter as diferenças entre o SDK autônomo e o SDK interno herdado, consulte o guia de migração.
Definir uma sub-orquestração
O exemplo a seguir ilustra um cenário de IoT em que vários dispositivos precisam ser configurados. A função representa o fluxo de trabalho de instalação executado para cada dispositivo:
Modelo de trabalho isolado
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: ...
}
Modelo em processo
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;
}
}
Esta função de orquestrador pode ser executada de forma autônoma para configuração única de dispositivos ou um orquestrador pai pode agendá-la como uma sub-orquestração usando a API call-sub-orchestrator.
Executar sub-orquestrações em paralelo
O exemplo a seguir mostra um orquestrador principal que distribui várias sub-orquestrações em paralelo. Algumas linguagens usam uma ID de instância filho determinística (derivada da ID da instância do pai mais um índice) para evitar sub-orquestrações duplicadas na reexecução.
Modelo de trabalho isolado
[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);
// ...
}
Modelo em processo
[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);
// ...
}
Próximas Etapas
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;
}
}