Partager via


Gestion des événements externes dans Fonctions durables (Azure Functions)

Les fonctions d’orchestrateur ont la capacité d’attendre et d’écouter des événements externes. Cette fonctionnalité de Fonctions durables est souvent utile pour gérer l’interaction humaine ou d’autres déclencheurs externes.

Notes

Les événements externes sont des opérations asynchrones unidirectionnelles. Ils ne sont pas adaptés aux situations où le client qui envoie l’événement a besoin d’une réponse synchrone de la fonction orchestrator.

Attendre des événements

L’API « wait-for-external-event » de la liaison de déclencheur d’orchestration permet à une fonction d’orchestrateur d’attendre et d’écouter de façon asynchrone un événement remis par un client externe. La fonction d’orchestrateur qui écoute déclare le nom de l’événement et la forme des données qu’il s’attend à recevoir.

[FunctionName("BudgetApproval")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    bool approved = await context.WaitForExternalEvent<bool>("Approval");
    if (approved)
    {
        // approval granted - do the approved action
    }
    else
    {
        // approval denied - send a notification
    }
}

Notes

Le code C# précédent correspond à Durable Functions 2.x. Pour Durable Functions 1.x, vous devez utiliser DurableOrchestrationContext au lieu de IDurableOrchestrationContext. Pour en savoir plus sur les différences entre les versions, consultez l’article Versions de Durable Functions.

Dans l’exemple précédent, la fonction écoute un événement unique spécifique et le traite après sa réception.

Vous pouvez écouter plusieurs événements simultanément, comme dans l’exemple suivant, où la fonction attend l’une des trois notifications d’événement possibles.

[FunctionName("Select")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var event1 = context.WaitForExternalEvent<float>("Event1");
    var event2 = context.WaitForExternalEvent<bool>("Event2");
    var event3 = context.WaitForExternalEvent<int>("Event3");

    var winner = await Task.WhenAny(event1, event2, event3);
    if (winner == event1)
    {
        // ...
    }
    else if (winner == event2)
    {
        // ...
    }
    else if (winner == event3)
    {
        // ...
    }
}

Notes

Le code C# précédent correspond à Durable Functions 2.x. Pour Durable Functions 1.x, vous devez utiliser DurableOrchestrationContext au lieu de IDurableOrchestrationContext. Pour en savoir plus sur les différences entre les versions, consultez l’article Versions de Durable Functions.

Dans l’exemple précédent, la fonction écoute tous les événements. Elle peut également attendre tous les événements.

[FunctionName("NewBuildingPermit")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    string applicationId = context.GetInput<string>();

    var gate1 = context.WaitForExternalEvent("CityPlanningApproval");
    var gate2 = context.WaitForExternalEvent("FireDeptApproval");
    var gate3 = context.WaitForExternalEvent("BuildingDeptApproval");

    // all three departments must grant approval before a permit can be issued
    await Task.WhenAll(gate1, gate2, gate3);

    await context.CallActivityAsync("IssueBuildingPermit", applicationId);
}

Notes

Le code précédent correspond à Durable Functions 2.x. Pour Durable Functions 1.x, vous devez utiliser DurableOrchestrationContext au lieu de IDurableOrchestrationContext. Pour en savoir plus sur les différences entre les versions, consultez l’article Versions de Durable Functions.

Dans .NET, si la charge utile de l’événement ne peut pas être convertie vers le type attendu T, une exception est levée.

L’API « wait-for-external-event » attend indéfiniment une entrée. L’application de fonction peut être déchargée en toute sécurité durant l’attente. Si et quand un événement arrive pour cette instance d’orchestration, elle est automatiquement réveillée et traite immédiatement l’événement.

Notes

Si votre application de fonction utilise le plan de consommation, aucun frais de facturation n’est encouru quand une fonction d’orchestrateur attend une tâche d’événement externe, quelle que soit la durée d’attente.

Comme pour les fonctions d’activité, les événements externes ont une garantie de remise au moins une fois. Cela signifie que, dans certaines conditions (comme les redémarrages, la mise à l’échelle, les incidents, etc.), votre application peut recevoir des doublons du même événement externe. Par conséquent, nous recommandons que les événements externes contiennent un genre d’ID qui leur permet d’être dédupliqués manuellement dans les orchestrateurs.

Envoyer des événements

Vous pouvez utiliser l’API « raise-event » définie par la liaison du client d’orchestration pour envoyer un événement externe à une orchestration. Vous pouvez également utiliser l’API HTTP de déclenchement d’événement pour envoyer un événement externe à une orchestration.

Un événement déclenché inclut les paramètres ID d’instance, eventName et eventData. Les fonctions d’orchestrateur gèrent ces événements à l’aide des API « wait-for-external-event ». Le paramètre eventName doit correspondre à la fois aux terminaisons d’envoi et de réception pour que l’événement soit traité. Les données d’événement doivent également être sérialisables au format JSON.

En interne, les mécanismes de « raise-event » mettent en file d’attente un message qui est récupéré par la fonction orchestrator en attente. Si l’instance n’est pas en attente sur le nom d’événement spécifié, le message d’événement est ajouté à une file d’attente en mémoire. Si l’instance d’orchestration commence ultérieurement à écouter ce nom d’événement, elle vérifiera si la file d’attente contient des messages d’événement.

Notes

S’il n’existe aucune instance d’orchestration avec la valeur d’ID d’instance spécifiée, le message d’événement est ignoré.

Voici un exemple de fonction déclenchée par une file d’attente qui envoie un événement « Approval » à une instance de la fonction d’orchestrateur. L’ID d’instance de l’orchestration provient du corps du message de file d’attente.

[FunctionName("ApprovalQueueProcessor")]
public static async Task Run(
    [QueueTrigger("approval-queue")] string instanceId,
    [DurableClient] IDurableOrchestrationClient client)
{
    await client.RaiseEventAsync(instanceId, "Approval", true);
}

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.

En interne, les mécanismes de « raise-event » mettent en file d’attente un message qui est récupéré par la fonction orchestrator en attente. Si l’instance n’est pas en attente sur le nom d’événement spécifié, le message d’événement est ajouté à la mémoire tampon. Si l’instance d’orchestration commence ultérieurement à écouter ce nom d’événement, elle vérifie la mémoire tampon des messages d’événement et déclenche la tâche qui l’attendait.

Notes

S’il n’existe aucune instance d’orchestration avec la valeur d’ID d’instance spécifiée, le message d’événement est ignoré.

HTTP

Voici un exemple de requête HTTP qui déclenche un événement « Approbation » pour une instance d’orchestration.

POST /runtime/webhooks/durabletask/instances/MyInstanceId/raiseEvent/Approval&code=XXX
Content-Type: application/json

"true"

Dans ce cas, l’ID d’instance est codé en dur sous la forme MyInstanceId.

Étapes suivantes