Partager via


Chaînage de fonctions

Le chaînage de fonctions est un modèle dans lequel vous exécutez une séquence d’activités dans l’ordre. Il est courant de passer la sortie d’une activité à l’entrée de la suivante. Cet article décrit la séquence de chaînage pour les kits SDK Durable Task pour .NET, JavaScript, Python et Java.

Functions

Cet article décrit ces fonctions dans l’exemple d’application :

  • E1_HelloSequence: fonction d’orchestrateur qui appelle E1_SayHello plusieurs fois en séquence. Il stocke chaque sortie et enregistre les résultats.
  • E1_SayHello : une fonction d'activité qui ajoute « Bonjour » au début d'une chaîne.
  • HttpStart: fonction client durable déclenchée par HTTP qui démarre une instance de l’orchestrateur.

Cet article décrit ces composants dans l’exemple d’application :

  • GreetingOrchestration, greetingOrchestrator, function_chaining_orchestrator ou ActivityChaining : un orchestrateur qui appelle plusieurs activités dans une séquence. Il stocke chaque sortie et enregistre les résultats.
  • Fonctions d’activité : activités qui traitent les entrées et retournent les résultats. Chaque activité effectue une transformation simple sur l’entrée.
  • Client : application cliente qui démarre une instance de l’orchestrateur et attend le résultat.

Un orchestrateur

[FunctionName("E1_HelloSequence")]
public static async Task<List<string>> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();

    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Tokyo"));
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Seattle"));
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello_DirectInput", "London"));

    // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
    return outputs;
}

Toutes les fonctions d’orchestration C# doivent avoir un paramètre de type DurableOrchestrationContext, qui existe dans l’assembly Microsoft.Azure.WebJobs.Extensions.DurableTask. Cet objet de contexte vous permet d’appeler d’autres fonctions d’activité et de passer les paramètres d’entrée à l’aide de sa méthode CallActivityAsync.

Le code appelle trois fois E1_SayHello en séquence avec des valeurs de paramètre différentes. La valeur renvoyée de chaque appel est ajoutée à la liste outputs, qui est retournée à la fin de la fonction.

Ce code montre un orchestrateur qui appelle trois activités dans la séquence et transmet chaque sortie à l’activité suivante :

using Microsoft.DurableTask;

[DurableTask]
public class GreetingOrchestration : TaskOrchestrator<string, string>
{
    public override async Task<string> RunAsync(TaskOrchestrationContext context, string name)
    {
        // Step 1: Say hello to the person
        string greeting = await context.CallActivityAsync<string>(nameof(SayHelloActivity), name);

        // Step 2: Process the greeting
        string processedGreeting = await context.CallActivityAsync<string>(nameof(ProcessGreetingActivity), greeting);

        // Step 3: Finalize the response
        string finalResponse = await context.CallActivityAsync<string>(nameof(FinalizeResponseActivity), processedGreeting);

        return finalResponse;
    }
}

Tous les orchestrateurs .NET héritent de TaskOrchestrator<TInput, TOutput>. Avec le TaskOrchestrationContext, vous pouvez appeler des activités à l’aide de CallActivityAsync. Le code appelle trois activités dans la séquence, où chaque activité reçoit la sortie de l’activité précédente.

Activity

[FunctionName("E1_SayHello")]
public static string SayHello([ActivityTrigger] IDurableActivityContext context)
{
    string name = context.GetInput<string>();
    return $"Hello {name}!";
}

Les activités utilisent l’attribut ActivityTrigger. Utiliser IDurableActivityContext pour les actions d’activité, telles que la lecture d’entrée avec GetInput<T>.

E1_SayHello met en forme une chaîne de salutation.

Au lieu de lier à IDurableActivityContext, liez directement au type passé dans la fonction d'activité. Par exemple :

[FunctionName("E1_SayHello_DirectInput")]
public static string SayHelloDirectInput([ActivityTrigger] string name)
{
    return $"Hello {name}!";
}

Les activités du SDK Durable Task héritent de TaskActivity<TInput, TOutput>:

using Microsoft.DurableTask;
using Microsoft.Extensions.Logging;

[DurableTask]
public class SayHelloActivity : TaskActivity<string, string>
{
    private readonly ILogger<SayHelloActivity> _logger;

    public SayHelloActivity(ILogger<SayHelloActivity> logger)
    {
        _logger = logger;
    }

    public override Task<string> RunAsync(TaskActivityContext context, string name)
    {
        _logger.LogInformation("Activity SayHello called with name: {Name}", name);
        return Task.FromResult($"Hello {name}!");
    }
}

[DurableTask]
public class ProcessGreetingActivity : TaskActivity<string, string>
{
    public override Task<string> RunAsync(TaskActivityContext context, string greeting)
    {
        return Task.FromResult($"{greeting} How are you today?");
    }
}

[DurableTask]
public class FinalizeResponseActivity : TaskActivity<string, string>
{
    public override Task<string> RunAsync(TaskActivityContext context, string response)
    {
        return Task.FromResult($"{response} I hope you're doing well!");
    }
}

Utilisez l’injection de dépendances pour obtenir des services comme ILogger. Ajoutez l’attribut [DurableTask] pour inscrire l’activité auprès du worker.

Client

Démarrez une instance de fonction d'orchestration à partir d’une fonction client. Utilisez la HttpStart fonction déclenchée par HTTP pour démarrer des instances de E1_HelloSequence.

public static class HttpStart
{
    [FunctionName("HttpStart")]
    public static async Task<HttpResponseMessage> Run(
        [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
        [DurableClient] IDurableClient 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}'.");

        return starter.CreateCheckStatusResponse(req, instanceId);
    }
}

Pour interagir avec des orchestrateurs, ajoutez une liaison d’entrée DurableClient . Utilisez le client pour démarrer une orchestration et retourner une réponse HTTP qui inclut des URL pour vérifier l’état de la nouvelle orchestration.

Démarrez une orchestration à partir d’une application cliente. Le client planifie l’orchestration et peut attendre la fin.

using Microsoft.DurableTask.Client;

// Create the client
var client = DurableTaskClientBuilder.UseDurableTaskScheduler(connectionString).Build();

// Schedule a new orchestration instance
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
    nameof(GreetingOrchestration),
    input: "World");

Console.WriteLine($"Started orchestration with ID: {instanceId}");

// Wait for the orchestration to complete
OrchestrationMetadata result = await client.WaitForInstanceCompletionAsync(
    instanceId,
    getInputsAndOutputs: true);

Console.WriteLine($"Orchestration completed with result: {result.ReadOutputAs<string>()}");

Créez le DurableTaskClient à l’aide d’une chaîne de connexion au Planificateur de tâches durable. Permet ScheduleNewOrchestrationInstanceAsync de démarrer une orchestration et WaitForInstanceCompletionAsync d’attendre la fin.

Exécution de l'exemple

Pour exécuter l’orchestration E1_HelloSequence , envoyez cette requête HTTP POST à la HttpStart fonction.

POST http://{host}/orchestrators/E1_HelloSequence

Remarque

L’extrait de code HTTP précédent suppose que le fichier host.json de l’exemple supprime le préfixe par défaut api/ de toutes les URL de fonction de déclencheur HTTP. Recherchez cette configuration dans le fichier host.json de l’exemple.

Par exemple, si vous exécutez l’exemple dans une application de fonction nommée myfunctionapp, remplacez {host} par myfunctionapp.azurewebsites.net.

La requête retourne HTTP 202 (rogné pour la concision) :

HTTP/1.1 202 Accepted
Content-Length: 719
Content-Type: application/json; charset=utf-8
Location: http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}

(...trimmed...)

Les files d’attente d’orchestration commencent à s’exécuter immédiatement. Utilisez l’URL dans l’en-tête Location pour vérifier l’état d’exécution.

GET http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}

La réponse affiche l’état de l’orchestration. Étant donné qu’elle se termine rapidement, l’instance est souvent dans l’état Terminé et retourne une réponse comme celle-ci (rogné pour la concision) :

HTTP/1.1 200 OK
Content-Length: 179
Content-Type: application/json; charset=utf-8

{"runtimeStatus":"Completed","input":null,"output":["Hello Tokyo!","Hello Seattle!","Hello London!"],"createdTime":"2017-06-29T05:24:57Z","lastUpdatedTime":"2017-06-29T05:24:59Z"}

L’instance runtimeStatus est terminée et output contient le résultat sérialisé JSON de l’exécution de la fonction d’orchestrateur.

Remarque

Implémentez une logique de démarrage similaire pour d’autres types de déclencheurs, tels que queueTrigger, eventHubTriggerou timerTrigger.

Passez en revue les journaux d’exécution de la fonction. La E1_HelloSequence fonction démarre et se termine plusieurs fois en raison du comportement de relecture décrit dans la fiabilité de l’orchestration. Mais E1_SayHello s’exécute seulement trois fois, car les exécutions de fonction d'activité ne se rejouent pas.

Pour exécuter l’exemple, vous avez besoin des éléments suivants :

  1. Démarrez l’émulateur Durable Task Scheduler (pour le développement local) :

    docker run -d -p 8080:8080 -p 8082:8082 --name dts-emulator mcr.microsoft.com/dts/dts-emulator:latest
    
  2. Démarrez le worker pour enregistrer l’orchestrateur et les activités.

  3. Exécutez le client pour planifier une orchestration et attendre le résultat.

La sortie du client affiche le résultat de l’orchestration chaînée :

Started orchestration with ID: abc123
Orchestration completed with result: "Hello World! How are you today? I hope you're doing well!"

Les journaux de travail affichent que chaque activité s’exécute en séquence et passe sa sortie à l’activité suivante.

Étapes suivantes

Cet exemple illustre une orchestration de chaînage de fonctions simple. Ensuite, implémentez le modèle fan-out/ventilateur-in.

Cet exemple illustre une orchestration de chaînage de fonctions simple. Ensuite, explorez d’autres modèles.

Pour obtenir des exemples complets du SDK JavaScript de Durable Task, consultez les exemples du SDK JavaScript de Durable Task.