Control de eventos externos con Durable Functions (Azure Functions)
Artikulua
Las funciones de orquestador tienen la capacidad de esperar y escuchar eventos externos. Esta característica de Durable Functions suele ser útil para controlar las interacciones humanas u otros desencadenadores externos.
Oharra
Los eventos externos son operaciones asincrónicas unidireccionales. No resultan adecuados para situaciones donde el cliente que envía el evento necesita una respuesta sincrónica de la función de orquestador.
Espera de eventos
La API "wait-for-external-event" del enlace del desencadenador de orquestación permite que una función del orquestador espere y escuche de forma asíncrona un evento entregado por un cliente externo. La función de orquestador de escucha declara el nombre del evento y la forma de los datos que espera recibir.
[FunctionName("BudgetApproval")]
publicstaticasync 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
}
}
Oharra
El código de C# anterior corresponde a Durable Functions 2.x. En el caso de Durable Functions 1.x, debe usar DurableOrchestrationContext en lugar de IDurableOrchestrationContext. Para obtener más información sobre las diferencias entre versiones, vea el artículo Versiones de Durable Functions.
JavaScript
const df = require("durable-functions");
module.exports = df.orchestrator(function*(context) {
const approved = yield context.df.waitForExternalEvent("Approval");
if (approved) {
// approval granted - do the approved action
} else {
// approval denied - send a notification
}
});
Python
import azure.functions as func
import azure.durable_functions as df
deforchestrator_function(context: df.DurableOrchestrationContext):
approved = yield context.wait_for_external_event('Approval')
if approved:
# approval granted - do the approved actionelse:
# approval denied - send a notification
main = df.Orchestrator.create(orchestrator_function)
PowerShell
param($Context)
$approved = Start-DurableExternalEventListener -EventName"Approval"if ($approved) {
# approval granted - do the approved action
} else {
# approval denied - send a notification
}
Java
@FunctionName("WaitForExternalEvent")
publicvoidwaitForExternalEvent(
@DurableOrchestrationTrigger(name = "ctx") TaskOrchestrationContext ctx) {
boolean approved = ctx.waitForExternalEvent("Approval", boolean.class).await();
if (approved) {
// approval granted - do the approved action
} else {
// approval denied - send a notification
}
}
El ejemplo anterior escucha un evento único específico y toma medidas cuando se recibe.
Puede escuchar varios eventos al mismo tiempo, al igual que en el ejemplo siguiente, que espera una de tres notificaciones de eventos posibles.
El código de C# anterior corresponde a Durable Functions 2.x. En el caso de Durable Functions 1.x, debe usar DurableOrchestrationContext en lugar de IDurableOrchestrationContext. Para obtener más información sobre las diferencias entre versiones, vea el artículo Versiones de Durable Functions.
[FunctionName("NewBuildingPermit")]
publicstaticasync 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 issuedawait Task.WhenAll(gate1, gate2, gate3);
await context.CallActivityAsync("IssueBuildingPermit", applicationId);
}
Oharra
El código anterior corresponde a Durable Functions 2.x. En el caso de Durable Functions 1.x, debe usar DurableOrchestrationContext en lugar de IDurableOrchestrationContext. Para obtener más información sobre las diferencias entre versiones, vea el artículo Versiones de Durable Functions.
En .NET, si la carga del evento no se puede convertir al tipo T esperado, se produce una excepción.
JavaScript
const df = require("durable-functions");
module.exports = df.orchestrator(function*(context) {
const applicationId = context.df.getInput();
const gate1 = context.df.waitForExternalEvent("CityPlanningApproval");
const gate2 = context.df.waitForExternalEvent("FireDeptApproval");
const gate3 = context.df.waitForExternalEvent("BuildingDeptApproval");
// all three departments must grant approval before a permit can be issuedyield context.df.Task.all([gate1, gate2, gate3]);
yield context.df.callActivity("IssueBuildingPermit", applicationId);
});
@FunctionName("NewBuildingPermit")
publicvoidnewBuildingPermit(
@DurableOrchestrationTrigger(name = "ctx") TaskOrchestrationContext ctx) {
String applicationId = ctx.getInput(String.class);
Task<Void> gate1 = ctx.waitForExternalEvent("CityPlanningApproval");
Task<Void> gate2 = ctx.waitForExternalEvent("FireDeptApproval");
Task<Void> gate3 = ctx.waitForExternalEvent("BuildingDeptApproval");
// all three departments must grant approval before a permit can be issued
ctx.allOf(List.of(gate1, gate2, gate3)).await();
ctx.callActivity("IssueBuildingPermit", applicationId).await();
}
La API "wait-for-external-event" espera indefinidamente alguna entrada. La aplicación de función puede descargarse con seguridad mientras espera. En el momento en que un evento llega a esta instancia de orquestación, esta se activa automáticamente y procesa de inmediato el evento.
Oharra
Si la aplicación de funciones usa el plan de consumo, no habrá cargos de facturación mientras una función del orquestador esté esperando una tarea de evento externa, sin importar el tiempo que espere.
Al igual que con las Funciones de actividad, los eventos externos tienen una garantía de entrega de al menos una vez. Esto significa que, en determinadas condiciones (como reinicios, escalado, bloqueos, etc.), la aplicación puede recibir duplicados del mismo evento externo. Por lo tanto, se recomienda que los eventos externos contengan algún tipo de identificador que les permita desduplicarse manualmente en orquestadores.
Envío de eventos
Puedes usar la API "raise-event" definida por el enlace del cliente de orquestación para enviar un evento externo a una orquestación. También puede usar la API de HTTP de generación de evento integrada para enviar un evento externo a una orquestación.
Un evento generado incluye valores de instance ID, eventName y eventData como parámetros. Las funciones de Orchestrator controlan estos eventos con las API "wait-for-external-event". El valor de eventName debe coincidir con los extremos de envío y recepción para que se procese el evento. Los datos del evento también se deben poder serializar con JSON.
De manera interna, los mecanismos de "raise-event" ponen en cola un mensaje que recoge la función de orquestador en espera. Si la instancia no está esperando el nombre de evento especificado, el mensaje del evento se agrega a una cola en memoria. Si la instancia de orquestación inicia posteriormente la escucha de ese nombre de evento, se comprobará si hay mensajes de eventos en la cola.
Oharra
Si no hay ninguna instancia de orquestación con el identificador de instancia especificado, se descartará el mensaje del evento.
A continuación se muestra una función desencadenada por la cola de ejemplo que envía un evento de aprobación a una instancia de la función de orquestador. El identificador de la instancia de orquestación procede del cuerpo del mensaje de la cola.
El código de C# anterior corresponde a Durable Functions 2.x. En el caso de Durable Functions 1.x, debe usar el atributo OrchestrationClient en lugar del atributo DurableClient, además de usar el tipo de parámetro DurableOrchestrationClient en lugar de IDurableOrchestrationClient. Para obtener más información sobre las diferencias entre versiones, vea el artículo Versiones de Durable Functions.
Internamente, la API "raise-event" pone en cola un mensaje que es recogido por la función del orquestador en espera. Si la instancia no espera el nombre de evento especificado, el mensaje de evento se agrega a un búfer en memoria. Si la instancia de orquestación comienza a escuchar ese nombre de evento más tarde, comprobará el búfer en busca de mensajes de evento y activará la tarea que estaba esperando.
Oharra
Si no hay ninguna instancia de orquestación con el identificador de instancia especificado, se descartará el mensaje del evento.
HTTP
A continuación, se muestra una solicitud HTTP que genera un evento de "Aprobación" para una instancia de orquestación.
HTTP
POST /runtime/webhooks/durabletask/instances/MyInstanceId/raiseEvent/Approval&code=XXX
Content-Type: application/json
"true"
En este caso, el id. de la instancia está codificado de forma rígida como MyInstanceId.
Bat egin IAren soluzio eskalagarrien soluzioak sortzeko topaketa sortarekin, mundu errealaren erabilera-kasuetan oinarrituak, beste garatzaile eta aditu batzuekin.
Aprenda a organizar un flujo de trabajo de larga duración como un conjunto de actividades mediante instancias escalables y rentables de Durable Functions.