Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Les fonctions d’orchestrateur peuvent appeler d’autres fonctions d’orchestrateur en tant que sous-orchestrations. Une sous-orchestration s’exécute en tant qu’enfant de l’orchestrateur appelant (parent) et se comporte comme une activité du point de vue de l’appelant : elle peut retourner une valeur, lever des exceptions interceptées par le parent et prendre en charge la nouvelle tentative automatique.
Quand utiliser des sous-orchestrations
Utilisez des sous-orchestrations lorsque vous devez :
- Composez des blocs de construction de flux de travail réutilisables : Extrayez un flux de travail en plusieurs étapes dans son propre orchestrateur afin que plusieurs orchestrations parentes puissent l’appeler.
- Orchestrations en parallèles : Planifiez simultanément de nombreuses instances du même orchestrateur et attendez que toutes ces orchestrations se terminent.
- Organiser des flux de travail complexes : Décomposez une grande orchestration en éléments nommés, testables au lieu d’une seule fonction longue.
Note
Les sous-orchestrations doivent être définies dans la même application que l’orchestration parente. Pour appeler des orchestrations dans une autre application, utilisez plutôt le modèle d’interrogation HTTP 202. Pour plus d’informations, consultez les fonctionnalités HTTP.
Contenu de cet article :
- Définir une sous-orchestration — Exemple d’approvisionnement à appareil unique
- Exécuter des sous-orchestrations en parallèle : modèle de fan-out avec des ID d’instance déterministes
Note
Dans PowerShell, les sous-orchestrations sont prises en charge uniquement dans le Kit de développement logiciel (SDK) autonome : AzureFunctions.PowerShell.Durable.SDK. Pour connaître les différences entre le Kit de développement logiciel (SDK) autonome et le SDK intégré hérité, consultez le guide de migration.
Définir une sous-orchestration
L’exemple suivant illustre un scénario IoT où plusieurs appareils doivent être configurés. La fonction représente le flux de travail d’installation qui s’exécute pour chaque appareil :
Modèle de travailleur isolé
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: ...
}
Modèle in-process
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;
}
}
Cette fonction d'orchestrateur peut s'exécuter de manière autonome pour la configuration d'un appareil unique, ou un orchestrateur parent peut la planifier en tant que sous-orchestration à l'aide de l'API call-sub-orchestrator.
Exécuter des sous-orchestrations en parallèle
L’exemple suivant montre un orchestrateur principal qui répartit plusieurs sous-orchestrations en parallèle. Certaines langues utilisent un ID d’instance enfant déterministe (dérivé de l’ID d’instance du parent et d’un index) pour empêcher les sous-orchestrations en double lors de la relecture.
Modèle de travailleur isolé
[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);
// ...
}
Modèle in-process
[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);
// ...
}
Étapes suivantes
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;
}
}