Gérer des instances dans Durable Functions dans Azure

Les orchestrations dans Durable Functions sont des fonctions avec état à exécution longue qui peuvent être démarrées, interrogées, suspendues, reprises et arrêtées à l’aide d’API de gestion intégrées. Plusieurs autres API de gestion d’instance sont également exposées par la liaison du client d’orchestration Durable Functions, par exemple l’envoi d’événements externes à des instances, la purge de l’historique des instances, etc. Cet article présente les détails de toutes les opérations de gestion des instances prises en charge.

Démarrer des instances

La méthode start-new (ou schedule-new) sur la liaison du client d’orchestration démarre une nouvelle instance d’orchestration. En interne, cette méthode écrit un message par le biais du fournisseur de stockage Durable Functions, puis retourne. Ce message déclenche de manière asynchrone le démarrage d’une fonction d’orchestration avec le nom spécifié.

Les paramètres de démarrage d’une nouvelle instance d’orchestration sont les suivants :

  • Name : Nom de la fonction orchestrator à planifier.
  • Entrée: Toutes les données JSON sérialisables devant être passées comme entrée à la fonction orchestrator.
  • InstanceId : (Facultatif) ID unique de l’instance. Si vous ne spécifiez pas ce paramètre, la méthode utilise un ID aléatoire.

Conseil

Utilisez un identificateur aléatoire pour l’ID d’instance quand cela est possible. Les ID d’instance aléatoires permettent de garantir une distribution égale de la charge lors de la mise à l’échelle des fonctions orchestrator sur plusieurs machines virtuelles. Le moment qui convient pour l’utilisation des ID d’instance non aléatoires correspond au moment où l’ID provient d’une source externe ou lors de l’implémentation du modèle orchestrateur singleton.

Le code suivant est un exemple de fonction qui démarre une nouvelle instance d’orchestration :

[FunctionName("HelloWorldQueueTrigger")]
public static async Task Run(
    [QueueTrigger("start-queue")] string input,
    [DurableClient] IDurableOrchestrationClient starter,
    ILogger log)
{
    string instanceId = await starter.StartNewAsync("HelloWorld", input);
    log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
}

Notes

Le code C# précédent correspond à Durable Functions 2.x. Pour Durable Functions 1.x, vous devez utiliser l’attribut OrchestrationClient au lieu de l’attribut DurableClient, et vous devez utiliser le type de paramètre DurableOrchestrationClient au lieu de IDurableOrchestrationClient. Pour en savoir plus sur les différences entre les versions, consultez l’article Versions de Durable Functions.

Azure Functions Core Tools

Vous pouvez également démarrer une instance directement avec la commande func durable start-new dans les Core Tools, qui utilise les paramètres suivants :

  • function-name (obligatoire) : Nom de la fonction à démarrer.
  • input (facultatif) : Entrée de la fonction, en ligne ou par le biais d’un fichier JSON. Pour les fichiers, ajoutez un préfixe au chemin du fichier avec @, par exemple, @path/to/file.json.
  • id (facultatif) : ID de l’instance d’orchestration. Si vous ne spécifiez pas ce paramètre, la commande utilise un GUID aléatoire.
  • connection-string-setting (facultatif) : Nom du paramètre d’application contenant la chaîne de connexion de stockage à utiliser. La valeur par défaut est AzureWebJobsStorage.
  • task-hub-name (facultatif) : Nom du hub de tâches Durable Functions à utiliser. La valeur par défaut est DurableFunctionsHub. Vous pouvez également le définir dans host.json à l’aide de durableTask:HubName.

Notes

Les commandes Core Tools supposent que vous les exécutiez à partir du répertoire racine d’une application de fonction. Si vous fournissez explicitement les paramètres connection-string-setting et task-hub-name, vous pouvez exécuter les commandes à partir de n’importe quel répertoire. Même si vous pouvez exécuter ces commandes sans exécuter d’hôte d’application de fonction, vous constaterez peut-être que vous ne pouvez pas observer certains effets si l’hôte n’est pas exécuté. Par exemple, la commande start-new met en file d’attente un message de démarrage dans le hub de tâches cible, mais l’orchestration ne peut pas réellement s’exécuter à moins d’avoir un processus hôte d’application de fonction en cours d’exécution pouvant traiter le message.

Notes

Les commandes Core Tools ne sont actuellement prises en charge que lors de l’utilisation du fournisseur Stockage Azure par défaut pour rendre l’état d’exécution persistant.

La commande suivante démarre la fonction nommée HelloWorld et lui passe le contenu du fichier counter-data.json :

func durable start-new --function-name HelloWorld --input @counter-data.json --task-hub-name TestTaskHub

Interroger des instances

Après le démarrage de nouvelles instances d’orchestration, vous devrez probablement interroger leur état d’exécution pour savoir si elles sont en cours d’exécution, si elles ont terminé ou si elles ont échoué.

La méthode get-status sur la liaison du client d’orchestration demande l’état d’une instance d’orchestration.

Elle prend instanceId (obligatoire), showHistory (facultatif), showHistoryOutput (facultatif) et showInput (facultatif) comme paramètres.

  • showHistory : Si la valeur est définie sur true, la réponse contient l’historique d’exécution.
  • showHistoryOutput : Si la valeur est définie sur true, l’historique d’exécution contient les sorties de l’activité.
  • showInput : Si la valeur est définie sur false, la réponse ne contient pas l’entrée de la fonction. La valeur par défaut est true.

La méthode renvoie un objet avec les propriétés suivantes :

  • Name : Nom de la fonction orchestrator.
  • InstanceId : ID d’instance de l’orchestration (doit être identique à l’entrée instanceId).
  • CreatedTime : Heure à laquelle la fonction orchestrator a commencé à s’exécuter.
  • LastUpdatedTime : Heure du dernier point de contrôle d’orchestration.
  • Entrée: Entrée de la fonction sous forme de valeur JSON. Ce champ n’est pas rempli si showInput est false.
  • CustomStatus : État personnalisé de l’orchestration au format JSON.
  • Sortie: Sortie de la fonction sous forme de valeur JSON (si cette fonction est terminée). En cas d’échec de la fonction d’orchestrateur, cette propriété inclut les détails de l’échec. En cas de suspension ou d’arrêt de la fonction de l’orchestrateur, cette propriété en indique la raison (s’il y en a une).
  • RuntimeStatus : une des valeurs suivantes :
    • Pending : L’instance a été planifiée mais n’est pas encore en cours d’exécution.
    • En cours d’exécution : L’instance a commencé à s’exécuter.
    • Completed : L’instance s’est terminée normalement.
    • ContinuedAsNew : L’instance a redémarré automatiquement avec un nouvel historique. Cet état est temporaire.
    • Échec : Échec de l’instance avec une erreur.
    • Terminé : L’instance a été brusquement arrêtée.
    • Suspended : l’instance a été suspendue et pourra être reprise ultérieurement.
  • History : L’historique d’exécution de l’orchestration. Ce champ est renseigné uniquement si showHistory est défini sur true.

Notes

Un orchestrateur n’est pas marqué comme Completed avant que toutes ses tâches planifiées soient terminées et que l’orchestrateur ait renvoyé son résultat. En d’autres termes, il n’est pas suffisant qu’un orchestrateur atteigne son instruction return pour qu’il soit marqué comme Completed. Cela s’avère particulièrement pertinent dans les cas où WhenAny est utilisé : ces orchestrateurs sont souvent return avant l’exécution de toutes les tâches planifiées.

Cette méthode renvoie null (.NET et Java), undefined (JavaScript) ou None (Python) si l’instance n’existe pas.

[FunctionName("GetStatus")]
public static async Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("check-status-queue")] string instanceId)
{
    DurableOrchestrationStatus status = await client.GetStatusAsync(instanceId);
    // do something based on the current status.
}

Notes

Le code C# précédent correspond à Durable Functions 2.x. Pour Durable Functions 1.x, vous devez utiliser l’attribut OrchestrationClient au lieu de l’attribut DurableClient, et vous devez utiliser le type de paramètre DurableOrchestrationClient au lieu de IDurableOrchestrationClient. Pour en savoir plus sur les différences entre les versions, consultez l’article Versions de Durable Functions.

Azure Functions Core Tools

Il est également possible d’obtenir l’état d’une instance d’orchestration à l’aide de la commande func durable get-runtime-status dans Core Tools.

Notes

Les commandes Core Tools ne sont actuellement prises en charge que lors de l’utilisation du fournisseur Stockage Azure par défaut pour rendre l’état d’exécution persistant.

La commande durable get-runtime-status utilise les paramètres suivants :

  • id (obligatoire) : ID de l’instance d’orchestration.
  • show-input (facultatif) : Si la valeur est définie sur true, la réponse contient l’entrée de la fonction. La valeur par défaut est false.
  • show-output (facultatif) : Si la valeur est définie sur true, la réponse contient la sortie de la fonction. La valeur par défaut est false.
  • connection-string-setting (facultatif) : Nom du paramètre d’application contenant la chaîne de connexion de stockage à utiliser. Par défaut, il s’agit de AzureWebJobsStorage.
  • task-hub-name (facultatif) : Nom du hub de tâches Durable Functions à utiliser. Par défaut, il s’agit de DurableFunctionsHub. Vous pouvez également le définir dans host.json, à l’aide de durableTask:HubName.

La commande suivante récupère l’état (y compris l’entrée et la sortie) d’une instance avec l’ID d’instance d’orchestration 0ab8c55a66644d68a3a8b220b12d209c. Cela suppose que la commande func est exécutée à partir du répertoire racine de l’application de fonction :

func durable get-runtime-status --id 0ab8c55a66644d68a3a8b220b12d209c --show-input true --show-output true

Vous pouvez utiliser la commande durable get-history pour récupérer l’historique d’une instance d’orchestration. Les paramètres suivants sont pris en compte :

  • id (obligatoire) : ID de l’instance d’orchestration.
  • connection-string-setting (facultatif) : Nom du paramètre d’application contenant la chaîne de connexion de stockage à utiliser. Par défaut, il s’agit de AzureWebJobsStorage.
  • task-hub-name (facultatif) : Nom du hub de tâches Durable Functions à utiliser. Par défaut, il s’agit de DurableFunctionsHub. Vous pouvez également le définir dans host.json à l’aide de durableTask:HubName.
func durable get-history --id 0ab8c55a66644d68a3a8b220b12d209c

Interroger toutes les instances

Vous pouvez utiliser des API dans votre Kit de développement logiciel (SDK) de langage pour interroger les états de toutes les instances d’orchestration dans votre hub de tâches. Cette API « list-instances » ou « get-status » retourne une liste d’objets qui représentent les instances de l’orchestration correspondant aux paramètres de la requête.

[FunctionName("GetAllStatus")]
public static async Task Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient client,
    ILogger log)
{
    var noFilter = new OrchestrationStatusQueryCondition();
    OrchestrationStatusQueryResult result = await client.ListInstancesAsync(
        noFilter,
        CancellationToken.None);
    foreach (DurableOrchestrationStatus instance in result.DurableOrchestrationState)
    {
        log.LogInformation(JsonConvert.SerializeObject(instance));
    }
    
    // Note: ListInstancesAsync only returns the first page of results.
    // To request additional pages provide the result.ContinuationToken
    // to the OrchestrationStatusQueryCondition's ContinuationToken property.
}

Notes

Le code C# précédent correspond à Durable Functions 2.x. Pour Durable Functions 1.x, vous devez utiliser l’attribut OrchestrationClient au lieu de l’attribut DurableClient, et vous devez utiliser le type de paramètre DurableOrchestrationClient au lieu de IDurableOrchestrationClient. Pour en savoir plus sur les différences entre les versions, consultez l’article Versions de Durable Functions.

Azure Functions Core Tools

Vous pouvez aussi interroger des instances directement à l’aide de la commande func durable get-instances dans Core Tools.

Notes

Les commandes Core Tools ne sont actuellement prises en charge que lors de l’utilisation du fournisseur Stockage Azure par défaut pour rendre l’état d’exécution persistant.

La commande durable get-instances utilise les paramètres suivants :

  • top (facultatif) : Cette commande prend en charge la pagination. Ce paramètre correspond au nombre d’instances récupérées par demande. La valeur par défaut est de 10.
  • continuation-token (facultatif) : Jeton qui indique la page ou la section des instances à récupérer. Chaque exécution de get-instances retourne un jeton à l’ensemble suivant d’instances.
  • connection-string-setting (facultatif) : Nom du paramètre d’application contenant la chaîne de connexion de stockage à utiliser. Par défaut, il s’agit de AzureWebJobsStorage.
  • task-hub-name (facultatif) : Nom du hub de tâches Durable Functions à utiliser. Par défaut, il s’agit de DurableFunctionsHub. Vous pouvez également le définir dans host.json, à l’aide de durableTask:HubName.
func durable get-instances

Interroger les instances en appliquant des filtres

Il est possible que vous n’ayez pas vraiment besoin de toutes les informations fournies par une requête d’instance standard. Peut-être avez-vous seulement besoin de connaître l’heure de création de l’orchestration ou de l’état de son exécution ? Vous pouvez affiner votre requête en appliquant des filtres.

[FunctionName("QueryStatus")]
public static async Task Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient client,
    ILogger log)
{
    // Get the first 100 running or pending instances that were created between 7 and 1 day(s) ago
    var queryFilter = new OrchestrationStatusQueryCondition
    {
        RuntimeStatus = new[]
        {
            OrchestrationRuntimeStatus.Pending,
            OrchestrationRuntimeStatus.Running,
        },
        CreatedTimeFrom = DateTime.UtcNow.Subtract(TimeSpan.FromDays(7)),
        CreatedTimeTo = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)),
        PageSize = 100,
    };
    
    OrchestrationStatusQueryResult result = await client.ListInstancesAsync(
        queryFilter,
        CancellationToken.None);
    foreach (DurableOrchestrationStatus instance in result.DurableOrchestrationState)
    {
        log.LogInformation(JsonConvert.SerializeObject(instance));
    }
}

Notes

Le code C# précédent correspond à Durable Functions 2.x. Pour Durable Functions 1.x, vous devez utiliser l’attribut OrchestrationClient au lieu de l’attribut DurableClient, et vous devez utiliser le type de paramètre DurableOrchestrationClient au lieu de IDurableOrchestrationClient. Pour en savoir plus sur les différences entre les versions, consultez l’article Versions de Durable Functions.

Azure Functions Core Tools

Dans Azure Functions Core Tools, vous pouvez également utiliser la commande durable get-instances avec des filtres. Outre les paramètres top, continuation-token, connection-string-setting et task-hub-name mentionnés ci-dessus, vous pouvez utiliser trois paramètres de filtre (created-after, created-before et runtime-status).

Notes

Les commandes Core Tools ne sont actuellement prises en charge que lors de l’utilisation du fournisseur Stockage Azure par défaut pour rendre l’état d’exécution persistant.

Voici les paramètres de la commande durable get-instances.

  • created-after (facultatif) : Récupère les instances créées après cette date/heure (UTC). Les dates et heures au format ISO 8601 sont acceptées.
  • created-before (facultatif) : Récupère les instances créées avant cette date/heure (UTC). Les dates et heures au format ISO 8601 sont acceptées.
  • runtime-status (facultatif) : Récupérez les instances avec un état particulier (par exemple, En cours d’exécution ou Terminé). Peut fournir plusieurs états (séparés par des espaces).
  • top (facultatif) : Nombre d’instances récupérées par requête. La valeur par défaut est de 10.
  • continuation-token (facultatif) : Jeton qui indique la page ou la section des instances à récupérer. Chaque exécution de get-instances retourne un jeton à l’ensemble suivant d’instances.
  • connection-string-setting (facultatif) : Nom du paramètre d’application contenant la chaîne de connexion de stockage à utiliser. Par défaut, il s’agit de AzureWebJobsStorage.
  • task-hub-name (facultatif) : Nom du hub de tâches Durable Functions à utiliser. Par défaut, il s’agit de DurableFunctionsHub. Vous pouvez également le définir dans host.json, à l’aide de durableTask:HubName.

Si vous n’appliquez pas de filtres (created-after, created-before ou runtime-status), la commande récupère simplement les instances top, sans se soucier de l’état de l’exécution ou de l’heure de création.

func durable get-instances --created-after 2021-03-10T13:57:31Z --created-before  2021-03-10T23:59Z --top 15

Arrêter les instances

Si vous disposez d’une instance d’orchestration dont l’exécution est trop longue, ou si vous devez simplement l’arrêter avant la fin pour une raison quelconque, vous avez la possibilité de l’arrêter.

Les deux paramètres de l'API de résiliation sont un ID d'instance et une chaîne de raison, qui sont écrits dans les journaux et dans l'état de l'instance.

[FunctionName("TerminateInstance")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("terminate-queue")] string instanceId)
{
    string reason = "Found a bug";
    return client.TerminateAsync(instanceId, reason);
}

Notes

Le code C# précédent correspond à Durable Functions 2.x. Pour Durable Functions 1.x, vous devez utiliser l’attribut OrchestrationClient au lieu de l’attribut DurableClient, et vous devez utiliser le type de paramètre DurableOrchestrationClient au lieu de IDurableOrchestrationClient. Pour en savoir plus sur les différences entre les versions, consultez l’article Versions de Durable Functions.

Une fois terminées, les instances passent à l’état Terminated. Toutefois, ce passage ne se produit pas immédiatement. En effet, l’opération de terminaison est mise en file d’attente dans le hub de tâches avec les autres opérations concernant cette instance. Vous pouvez utiliser les API d’interrogation d’instance pour savoir à quel moment une instance terminée est passée à l’état Terminated.

Notes

Il n’est pas possible de propager l’arrêt des instances. Les fonctions et sous-orchestrations de l’activité s’exécutent jusqu’à la fin, même si l’instance d’orchestration qui les a appelées a été arrêtée.

Suspendre et reprendre des instances

La suspension d’une orchestration vous permet d’interrompre une orchestration en cours d’exécution. Contrairement à l’arrêt, la suspension vous permet de reprendre un orchestrateur suspendu ultérieurement.

Les deux paramètres de l’API de suspension sont un ID d’instance et une chaîne de raison, qui sont écrits dans les journaux et dans l’état de l’instance.

[FunctionName("SuspendResumeInstance")]
public static async Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("suspend-resume-queue")] string instanceId)
{
    string suspendReason = "Need to pause workflow";
    await client.SuspendAsync(instanceId, suspendReason);
    
    // Wait for 30 seconds to ensure that the orchestrator state is updated to suspended. 
    DateTime dueTime = context.CurrentUtcDateTime.AddSeconds(30);
    await context.CreateTimer(dueTime, CancellationToken.None);
    
    string resumeReason = "Continue workflow";
    await client.ResumeAsync(instanceId, resumeReason);
}

Une instance suspendue passera finalement à l’état Suspended. Toutefois, ce passage ne se produit pas immédiatement. En effet, l’opération de suspension est mise en file d’attente dans le hub de tâches avec les autres opérations concernant cette instance. Vous pouvez utiliser les API d’interrogation d’instance pour savoir à quel moment une instance exécutée passe effectivement à l’état Suspended.

Quand un orchestrateur suspendu est repris, son état revient à Running.

Azure Functions Core Tools

Vous pouvez aussi directement arrêter une instance d’orchestration, à l’aide de la commande func durable terminate dans Core Tools.

Notes

Les commandes Core Tools ne sont actuellement prises en charge que lors de l’utilisation du fournisseur Stockage Azure par défaut pour rendre l’état d’exécution persistant.

La commande durable terminate utilise les paramètres suivants :

  • id (obligatoire) : ID de l’instance d’orchestration à arrêter.
  • reason (facultatif) : Raison de l’arrêt.
  • connection-string-setting (facultatif) : Nom du paramètre d’application contenant la chaîne de connexion de stockage à utiliser. Par défaut, il s’agit de AzureWebJobsStorage.
  • task-hub-name (facultatif) : Nom du hub de tâches Durable Functions à utiliser. Par défaut, il s’agit de DurableFunctionsHub. Vous pouvez également le définir dans host.json, à l’aide de durableTask:HubName.

La commande suivante arrête une instance d’orchestration avec l’ID 0ab8c55a66644d68a3a8b220b12d209c :

func durable terminate --id 0ab8c55a66644d68a3a8b220b12d209c --reason "Found a bug"

Envoyer des événements à des instances

Dans certains scénarios, les fonctions d’orchestrateur doivent attendre et écouter les événements externes. Les scénarios de surveillance et d’interaction humaine sont des exemples de scénarios où cela est utile.

Vous pouvez envoyer des notifications d'événements aux instances en cours d'exécution en utilisant l'API raise event de l’orchestration client. Les orchestrations peuvent écouter et répondre à ces événements à l’aide de l’API d’orchestrateur wait for external event.

Les paramètres de raise event sont les suivants :

  • ID d’instance : ID unique de l’instance.
  • Nom de l’événement : nom de l’événement à envoyer.
  • Données de l’événement : charge utile JSON sérialisable à envoyer à l’instance.
[FunctionName("RaiseEvent")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("event-queue")] string instanceId)
{
    int[] eventData = new int[] { 1, 2, 3 };
    return client.RaiseEventAsync(instanceId, "MyEvent", eventData);
}

Notes

Le code C# précédent correspond à Durable Functions 2.x. Pour Durable Functions 1.x, vous devez utiliser l’attribut OrchestrationClient au lieu de l’attribut DurableClient, et vous devez utiliser le type de paramètre DurableOrchestrationClient au lieu de IDurableOrchestrationClient. Pour en savoir plus sur les différences entre les versions, consultez l’article Versions de Durable Functions.

Notes

S’il n’existe aucune instance d’orchestration avec l’ID d’instance spécifié, le message d’événement est ignoré. Si une instance existe, mais qu’elle n’attend pas encore l’événement, ce dernier est stocké dans l’état de l’instance jusqu’à ce qu’il soit prêt à être reçu et traité.

Azure Functions Core Tools

Vous pouvez aussi déclencher un événement dans une instance d’orchestration, à l’aide de la commande func durable raise-event dans Core Tools.

Notes

Les commandes Core Tools ne sont actuellement prises en charge que lors de l’utilisation du fournisseur Stockage Azure par défaut pour rendre l’état d’exécution persistant.

La commande durable raise-event utilise les paramètres suivants :

  • id (obligatoire) : ID de l’instance d’orchestration.
  • event-name : Nom de l’événement à déclencher.
  • event-data (facultatif) : Données à envoyer à l’instance d’orchestration. Il peut s’agir d’un chemin de fichier JSON. Vous pouvez également fournir les données directement sur la ligne de commande.
  • connection-string-setting (facultatif) : Nom du paramètre d’application contenant la chaîne de connexion de stockage à utiliser. Par défaut, il s’agit de AzureWebJobsStorage.
  • task-hub-name (facultatif) : Nom du hub de tâches Durable Functions à utiliser. Par défaut, il s’agit de DurableFunctionsHub. Vous pouvez également le définir dans host.json, à l’aide de durableTask:HubName.
func durable raise-event --id 0ab8c55a66644d68a3a8b220b12d209c --event-name MyEvent --event-data @eventdata.json
func durable raise-event --id 1234567 --event-name MyOtherEvent --event-data 3

Attendre la fin de l’orchestration

Dans les orchestrations à exécution longue, vous pouvez souhaiter attendre les résultats de l’orchestration. Dans ce cas, il est également utile de définir un délai d’attente pour l’orchestration. Si le délai d’attente est dépassé, l’état de l’orchestration doit être retourné à la place des résultats.

L’API « wait for completion or create check status response » peut être utilisée pour obtenir la sortie réelle d’une instance d’orchestration de manière synchrone. Par défaut, cette méthode a un délai d’expiration par défaut de 10 secondes et un intervalle d’interrogation de 1 seconde.

Voici un exemple de fonction de déclencheur HTTP qui montre comment utiliser cette API :

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;

namespace VSSample
{
    public static class HttpSyncStart
    {
        private const string Timeout = "timeout";
        private const string RetryInterval = "retryInterval";

        [FunctionName("HttpSyncStart")]
        public static async Task<HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}/wait")]
            HttpRequestMessage req,
            [DurableClient] IDurableOrchestrationClient starter,
            string functionName,
            ILogger log)
        {
            // Function input comes from the request content.
            object eventData = await req.Content.ReadAsAsync<object>();
            string instanceId = await starter.StartNewAsync(functionName, eventData);

            log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

            TimeSpan timeout = GetTimeSpan(req, Timeout) ?? TimeSpan.FromSeconds(30);
            TimeSpan retryInterval = GetTimeSpan(req, RetryInterval) ?? TimeSpan.FromSeconds(1);
            
            return await starter.WaitForCompletionOrCreateCheckStatusResponseAsync(
                req,
                instanceId,
                timeout,
                retryInterval);
        }

        private static TimeSpan? GetTimeSpan(HttpRequestMessage request, string queryParameterName)
        {
            string queryParameterStringValue = request.RequestUri.ParseQueryString()[queryParameterName];
            if (string.IsNullOrEmpty(queryParameterStringValue))
            {
                return null;
            }

            return TimeSpan.FromSeconds(double.Parse(queryParameterStringValue));
        }
    }
}

Appelez la fonction avec la ligne suivante. Utilisez une valeur de 2 secondes pour le délai d’attente et de 0,5 seconde pour l’intervalle avant nouvelle tentative :

curl -X POST "http://localhost:7071/orchestrators/E1_HelloSequence/wait?timeout=2&retryInterval=0.5"

Notes

La commande cURL ci-dessus suppose que vous disposez d’une fonction d’orchestrateur nommée E1_HelloSequence dans votre projet. En raison de la façon dont la fonction de déclencheur HTTP est écrite, vous pouvez la remplacer par le nom de n’importe quelle fonction d’orchestrateur dans votre projet.

Selon le temps nécessaire pour obtenir la réponse de l’instance d’orchestration, il existe deux cas de figure :

  • Les instances d’orchestration sont terminées dans le délai imparti (dans ce cas, 2 secondes). La réponse est la sortie d’instance d’orchestration qui est remise de manière synchrone :
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Thu, 14 Dec 2021 06:14:29 GMT
Transfer-Encoding: chunked

[
    "Hello Tokyo!",
    "Hello Seattle!",
    "Hello London!"
]
HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
Date: Thu, 14 Dec 2021 06:13:51 GMT
Location: http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177?taskHub={taskHub}&connection={connection}&code={systemKey}
Retry-After: 10
Transfer-Encoding: chunked

{
    "id": "d3b72dddefce4e758d92f4d411567177",
    "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/raiseEvent/{eventName}?taskHub={taskHub}&connection={connection}&code={systemKey}",
    "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177?taskHub={taskHub}&connection={connection}&code={systemKey}",
    "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/terminate?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}",
    "suspendPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/suspend?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}",
    "resumePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/resume?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}"
}

Notes

Le format des URL webhook peut varier selon la version de l’hôte Azure Functions que vous exécutez. L’exemple précédent utilise l’hôte Azure Functions 3.0.

Récupérer les URL webhook de gestion HTTP

Vous pouvez utiliser un système externe pour superviser ou déclencher des événements au sein d’une orchestration. Les systèmes externes peuvent communiquer avec Durable Functions via les URL webhook qui font partie de la réponse par défaut décrite dans Découverte de l’URL de l’API HTTP. Vous pouvez également accéder par programme aux URL du webhook à l’aide de la liaison du client d’orchestration. Plus précisément, l’API create HTTP management payload peut être utilisée pour obtenir un objet sérialisable qui contient ces URL de webhook.

L’API create HTTP management payload crée un paramètre :

  • ID d’instance : ID unique de l’instance.

Les méthodes renvoient un objet avec les propriétés de chaîne suivantes :

  • Id : ID d’instance de l’orchestration (doit être identique à l’entrée InstanceId).
  • StatusQueryGetUri : L’URL de l’état de l’instance d’orchestration.
  • SendEventPostUri : L’URL « Raise event » de l’instance d’orchestration.
  • TerminatePostUri : L’URL « d’arrêt » de l’instance d’orchestration.
  • PurgeHistoryDeleteUri : URL de « purge de l’historique » de l’instance d’orchestration.
  • suspendPostUri : URL de « suspension » de l’instance de l’orchestration.
  • resumePostUri : URL de « reprise » de l’instance de l’orchestration.

Les fonctions peuvent envoyer des instances de ces objets à des systèmes externes pour surveiller ou déclencher des événements sur les orchestrations correspondantes, comme indiqué dans les exemples suivants :

[FunctionName("SendInstanceInfo")]
public static void SendInstanceInfo(
    [ActivityTrigger] IDurableActivityContext ctx,
    [DurableClient] IDurableOrchestrationClient client,
    [CosmosDB(
        databaseName: "MonitorDB",
        containerName: "HttpManagementPayloads",
        Connection = "CosmosDBConnectionSetting")]out dynamic document)
{
    HttpManagementPayload payload = client.CreateHttpManagementPayload(ctx.InstanceId);

    // send the payload to Azure Cosmos DB
    document = new { Payload = payload, id = ctx.InstanceId };
}

Notes

Le code C# précédent correspond à Durable Functions 2.x. Pour Durable Functions 1.x, vous devez utiliser l’attribut DurableActivityContext au lieu de l’attribut IDurableActivityContext, et vous devez utiliser l’attribut OrchestrationClient au lieu de l’attribut DurableClient, et devez utiliser le type de paramètre DurableOrchestrationClient et non IDurableOrchestrationClient. Pour en savoir plus sur les différences entre les versions, consultez l’article Versions de Durable Functions.

Rembobiner des instances (préversion)

Si une orchestration échoue pour une raison quelconque, vous pouvez rembobiner l’instance vers un état sain précédent à l’aide d’une API intégrée à cet effet.

Notes

Cette API n’est pas destinée à se substituer à des stratégies appropriées de nouvelles tentatives et de gestion des erreurs. Son utilisation est plutôt uniquement réservée dans les cas où les instances d’orchestration échouent pour des raisons inattendues. Les orchestrations dans des états autres que Failed (par exemple, Running, Pending, Terminated et Completed) ne peuvent pas être « rembobinées ». Pour en savoir plus sur les stratégies de gestion des nouvelles tentatives et des erreurs, consultez l’article Gestion des erreurs.

Utilisez la méthode RewindAsync (.NET) ou rewind (JavaScript) de la liaison du client d’orchestration pour replacer l’orchestration à l’état Exécution en cours. Cette méthode réexécute également l’activité ou la sous-orchestration qui a échoué et provoqué l’échec de l’orchestration.

Par exemple, supposons que vous ayez un workflow impliquant une suite d’approbations humaines. Supposons que vous ayez une suite de fonctions d’activité qui informe une personne que son approbation est nécessaire, et qui attend la réponse en temps réel. Une fois que toutes les activités d’approbation ont reçu des réponses ou ont expiré, supposons qu’une autre activité échoue en raison d’un problème de configuration d’application (par exemple, une chaîne de connexion de base de données non valide). Il en résulte un échec de l’orchestration, survenu en profondeur dans le workflow. Avec l’API RewindAsync (.NET) ou rewind (JavaScript), un administrateur d’application peut corriger l’erreur de configuration et rembobiner (rewind) l’orchestration ayant échoué jusqu’à l’état situé immédiatement avant l’échec. Aucune des étapes nécessitant une interaction humaine ne doit être approuvée de nouveau ; l’orchestration peut désormais s’effectuer correctement.

Notes

La fonctionnalité de rembobinage ne prend pas en charge le rembobinage des instances d’orchestration qui utilisent des minuteurs durables.

[FunctionName("RewindInstance")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("rewind-queue")] string instanceId)
{
    string reason = "Orchestrator failed and needs to be revived.";
    return client.RewindAsync(instanceId, reason);
}

Notes

Le code C# précédent correspond à Durable Functions 2.x. Pour Durable Functions 1.x, vous devez utiliser l’attribut OrchestrationClient au lieu de l’attribut DurableClient, et vous devez utiliser le type de paramètre DurableOrchestrationClient au lieu de IDurableOrchestrationClient. Pour en savoir plus sur les différences entre les versions, consultez l’article Versions de Durable Functions.

Azure Functions Core Tools

Vous pouvez aussi rembobiner une instance d’orchestration, à l’aide de la commande func durable rewind dans Core Tools.

Notes

Les commandes Core Tools ne sont actuellement prises en charge que lors de l’utilisation du fournisseur Stockage Azure par défaut pour rendre l’état d’exécution persistant.

La commande durable rewind utilise les paramètres suivants :

  • id (obligatoire) : ID de l’instance d’orchestration.
  • reason (facultatif) : Motif de rembobinage de l’instance d’orchestration.
  • connection-string-setting (facultatif) : Nom du paramètre d’application contenant la chaîne de connexion de stockage à utiliser. Par défaut, il s’agit de AzureWebJobsStorage.
  • task-hub-name (facultatif) : Nom du hub de tâches Durable Functions à utiliser. Par défaut, le nom du hub de tâches dans le fichier host.json est utilisé.
func durable rewind --id 0ab8c55a66644d68a3a8b220b12d209c --reason "Orchestrator failed and needs to be revived."

Vider l’historique des instances

Pour supprimer toutes les données associées à une orchestration, vous pouvez vider l’historique des instances. Par exemple, vous pouvez vouloir supprimer toutes les ressources de stockage associées à une instance terminée. Pour ce faire, utilisez l’API purge instance définie par le client d’orchestration.

Ce premier exemple montre comment vider une instance d’orchestration unique.

[FunctionName("PurgeInstanceHistory")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("purge-queue")] string instanceId)
{
    return client.PurgeInstanceHistoryAsync(instanceId);
}

L’exemple suivant affiche une fonction déclenchée, par un minuteur, qui purge l’historique de toutes les instances d’orchestration terminées après l’intervalle de temps spécifié. Dans ce cas, elle supprime les données de toutes les instances terminées depuis 30 jours ou plus. Cet exemple de fonction est programmé pour s’exécuter une fois par jour, à midi UTC :

[FunctionName("PurgeInstanceHistory")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [TimerTrigger("0 0 12 * * *")] TimerInfo myTimer)
{
    return client.PurgeInstanceHistoryAsync(
        DateTime.MinValue,
        DateTime.UtcNow.AddDays(-30),  
        new List<OrchestrationStatus>
        {
            OrchestrationStatus.Completed
        });
}

Notes

Le code C# précédent correspond à Durable Functions 2.x. Pour Durable Functions 1.x, vous devez utiliser l’attribut OrchestrationClient au lieu de l’attribut DurableClient, et vous devez utiliser le type de paramètre DurableOrchestrationClient au lieu de IDurableOrchestrationClient. Pour en savoir plus sur les différences entre les versions, consultez l’article Versions de Durable Functions.

Notes

Pour que cette opération aboutisse, l’état d’exécution de l’instance cible doit être Terminé, Terminé ou Échec.

Azure Functions Core Tools

Vous pouvez aussi supprimer définitivement l’historique d’une instance d’orchestration, à l’aide de la commande func durable purge-history dans Core Tools. Tout comme dans le deuxième exemple C# de la section précédente, elle vide l’historique de toutes les instances d’orchestration créées dans un intervalle de temps spécifié. Vous pouvez filtrer encore davantage les instances vidées, selon leur état d’exécution.

Notes

Les commandes Core Tools ne sont actuellement prises en charge que lors de l’utilisation du fournisseur Stockage Azure par défaut pour rendre l’état d’exécution persistant.

La commande durable purge-history a plusieurs paramètres :

  • created-after (facultatif) : Purge l’historique des instances créées après cette date/heure (UTC). Les dates et heures au format ISO 8601 sont acceptées.
  • created-before (facultatif) : Purge l’historique des instances créées avant cette date/heure (UTC). Les dates et heures au format ISO 8601 sont acceptées.
  • runtime-status (facultatif) : Videz l’historique des instances avec un état particulier (par exemple, Running ou Completed). Peut fournir plusieurs états (séparés par des espaces).
  • connection-string-setting (facultatif) : Nom du paramètre d’application contenant la chaîne de connexion de stockage à utiliser. Par défaut, il s’agit de AzureWebJobsStorage.
  • task-hub-name (facultatif) : Nom du hub de tâches Durable Functions à utiliser. Par défaut, le nom du hub de tâches dans le fichier host.json est utilisé.

La commande suivante supprime l’historique de toutes les instances qui ont été créées avant le 14 novembre 2021 à 19:35 (UTC) et qui ont échoué.

func durable purge-history --created-before 2021-11-14T19:35:00.0000000Z --runtime-status failed

Supprimer un hub de tâches

À l’aide de la commande func durable delete-task-hub dans Core Tools, vous pouvez supprimer tous les artefacts de stockage associés à un concentrateur de tâches particulier, notamment les tables de stockage, les files d’attente et les objets blob Azure.

Notes

Les commandes Core Tools ne sont actuellement prises en charge que lors de l’utilisation du fournisseur Stockage Azure par défaut pour rendre l’état d’exécution persistant.

La commande durable delete-task-hub a deux paramètres :

  • connection-string-setting (facultatif) : Nom du paramètre d’application contenant la chaîne de connexion de stockage à utiliser. Par défaut, il s’agit de AzureWebJobsStorage.
  • task-hub-name (facultatif) : Nom du hub de tâches Durable Functions à utiliser. Par défaut, le nom du hub de tâches dans le fichier host.json est utilisé.

La commande suivante supprime toutes les données de stockage Azure associées au hub de tâches UserTest.

func durable delete-task-hub --task-hub-name UserTest

Étapes suivantes