Hantera externa händelser i Durable Functions (Azure Functions)
Orchestrator-funktioner har möjlighet att 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.
Kommentar
Externa händelser är envägsasynkrona å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ör orkestreringsutlösarbindningen gör att en orchestrator-funktion asynkront kan vänta och lyssna efter en händelse som levereras av en extern klient. Den lyssnande orchestrator-funktionen deklarerar namnet på händelsen och formen på de data som förväntas 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
}
}
Kommentar
Den tidigare C#-koden ä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 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)
{
// ...
}
}
Kommentar
Den tidigare C#-koden ä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 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);
}
Kommentar
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 versioner finns i artikeln Durable Functions-versioner .
Om händelsenyttolasten inte kan konverteras till den förväntade typen T
i .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 händelsen omedelbart.
Kommentar
Om din funktionsapp använder förbrukningsplanen debiteras inga faktureringsavgifter medan en orkestreringsfunktion väntar på en extern händelseaktivitet, oavsett hur länge den väntar.
Precis som med Aktivitetsfunktioner har externa händelser en leveransgaranti minst en gång . Det innebär att programmet under vissa förhållanden (till exempel omstarter, skalning, krascher osv.) kan ta emot dubbletter av samma externa händelse. Därför rekommenderar vi att externa händelser innehåller någon form av ID som gör att de kan avdupliceras manuellt i orchestrators.
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 höjningshändelse 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 "wait-for-external-event". EventName måste matcha både sändnings- och mottagarsluten för att händelsen ska kunna bearbetas. Händelsedata måste också vara JSON-serialiserbara.
Internt anger mekanismerna "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 kön efter händelsemeddelanden.
Kommentar
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 "Approval"-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);
}
Kommentar
Den tidigare C#-koden är 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 versioner finns i artikeln Durable Functions-versioner .
Internt visar API:et "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 buffert. Om orkestreringsinstansen senare börjar lyssna efter det händelsenamnet kontrollerar den bufferten efter händelsemeddelanden och utlöser den uppgift som väntade på den.
Kommentar
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.