Hantera externa händelser i Durable Functions (Azure Functions)

Orchestrator-funktioner kan vänta och lyssna efter externa händelser. Den här funktionen i Durable Functions är ofta användbar för att hantera mänsklig interaktion eller andra externa utlösare.

Anteckning

Externa händelser är enkelriktade asynkrona åtgärder. De är inte lämpliga för situationer där klienten som skickar händelsen behöver ett synkront svar från orchestrator-funktionen.

Vänta på händelser

API :et "wait-for-external-event" förorkestreringsutlösarbindningen gör att en orkestreringsfunktion kan vänta asynkront och lyssna efter en händelse som levereras av en extern klient. Lyssningsorkestreringsfunktionen deklarerar namnet på händelsen och formen på de data som den förväntar sig att ta emot.

[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
    }
}

Anteckning

Den tidigare C#-koden gäller för Durable Functions 2.x. För Durable Functions 1.x måste du använda DurableOrchestrationContext i stället för IDurableOrchestrationContext. Mer information om skillnaderna mellan olika versioner finns i artikeln Durable Functions versioner.

Föregående exempel lyssnar efter en specifik enskild händelse och vidtar åtgärder när den tas emot.

Du kan lyssna efter flera händelser samtidigt, som i följande exempel, som väntar på någon av tre möjliga händelseaviseringar.

[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)
    {
        // ...
    }
}

Anteckning

Den tidigare C#-koden gäller för Durable Functions 2.x. För Durable Functions 1.x måste du använda DurableOrchestrationContext i stället för IDurableOrchestrationContext. Mer information om skillnaderna mellan olika versioner finns i artikeln Durable Functions versioner.

Föregående exempel lyssnar efter någon av flera händelser. Det går också att vänta på alla händelser.

[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);
}

Anteckning

Föregående kod är för Durable Functions 2.x. För Durable Functions 1.x måste du använda DurableOrchestrationContext i stället för IDurableOrchestrationContext. Mer information om skillnaderna mellan olika versioner finns i artikeln Durable Functions versioner.

Om händelsenyttolasten inte kan konverteras till den förväntade typen Ti .NET genereras ett undantag.

API :et "wait-for-external-event" väntar på obestämd tid på vissa indata. Funktionsappen kan tas bort på ett säkert sätt i väntan. Om och när en händelse anländer för den här orkestreringsinstansen aktiveras den automatiskt och bearbetar omedelbart händelsen.

Anteckning

Om din funktionsapp använder förbrukningsplanen tillkommer inga faktureringsavgifter medan en orkestreringsfunktion väntar på en extern händelseaktivitet, oavsett hur lång tid den väntar.

Skicka händelser

Du kan använda API:et "raise-event" som definieras av orkestreringsklientbindningen för att skicka en extern händelse till en orkestrering. Du kan också använda det inbyggda HTTP-API :et för att generera händelser för att skicka en extern händelse till en orkestrering.

En upphöjd händelse innehåller ett instans-ID, ett eventName och eventData som parametrar. Orchestrator-funktioner hanterar dessa händelser med api:erna "vänta på extern händelse" . EventName måste matcha både sändnings- och mottagningssluten för att händelsen ska kunna bearbetas. Händelsedata måste också vara JSON-serialiserbara.

Internt ställer mekanismerna för "raise-event" ett meddelande som hämtas av den väntande orkestreringsfunktionen. Om instansen inte väntar på det angivna händelsenamnet läggs händelsemeddelandet till i en minnesintern kö. Om orkestreringsinstansen senare börjar lyssna efter det händelsenamnet kontrollerar den om det finns händelsemeddelanden i kön.

Anteckning

Om det inte finns någon orkestreringsinstans med det angivna instans-ID:t ignoreras händelsemeddelandet.

Nedan visas ett exempel på en köutlöst funktion som skickar en "Godkännande"-händelse till en orchestrator-funktionsinstans. Orkestreringsinstans-ID:t kommer från brödtexten i kömeddelandet.

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

Anteckning

Den tidigare C#-koden gäller för Durable Functions 2.x. För Durable Functions 1.x måste du använda OrchestrationClient attributet i stället för DurableClient attributet och du måste använda DurableOrchestrationClient parametertypen i stället för IDurableOrchestrationClient. Mer information om skillnaderna mellan olika versioner finns i artikeln Durable Functions versioner.

Internt lägger API:et "raise-event" fram ett meddelande som hämtas av den väntande orchestrator-funktionen. Om instansen inte väntar på det angivna händelsenamnet läggs händelsemeddelandet till i en minnesintern buffert. Om orkestreringsinstansen senare börjar lyssna efter händelsenamnet kontrollerar den bufferten efter händelsemeddelanden och utlöser uppgiften som väntade på den.

Anteckning

Om det inte finns någon orkestreringsinstans med det angivna instans-ID:t ignoreras händelsemeddelandet.

HTTP

Följande är ett exempel på en HTTP-begäran som genererar en "Godkännande"-händelse till en orkestreringsinstans.

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

"true"

I det här fallet är instans-ID:t hårdkodat som MyInstanceId.

Nästa steg