Orquestaciones infinitas en Durable Functions (Azure Functions)
Artículo
Las orquestaciones infinitas son funciones de orquestador que nunca terminan. Son útiles si desea usar Durable Functions con agregadores y con cualquier escenario que requiera un bucle infinito.
Historial de orquestación
Como se explica en el tema del historial de orquestación, Durable Task Framework realiza un seguimiento del historial de cada función de orquestación. Este historial crecerá continuamente siempre y cuando la función de orquestador siga programando nuevo trabajo. Si la función de orquestador entra en un bucle infinito y programa trabajo continuamente, este historial podría alcanzar un tamaño crítico y provocar problemas de rendimiento considerables. El concepto de orquestación infinita se diseñó para mitigar este tipo de problemas en aplicaciones que necesitan bucles infinitos.
Restablecimiento y reinicio
En lugar de usar bucles infinitos, las funciones del orquestador restablecen su estado mediante una llamada al método continue-as-new del enlace del desencadenador de orquestación. Este método toma un parámetro serializable con JSON, que se convierte en la nueva entrada para la siguiente generación de función de orquestador.
Cuando se llama a continue-as-new, la instancia de orquestación se reinicia con el nuevo valor de entrada. Se mantiene el mismo identificador de instancia, pero se reinicia el historial de la función orquestadora.
Nota
El Durable Task Framework mantiene el mismo identificador de instancia pero crea internamente un nuevo identificador de ejecución para la función del orquestador que se reinicia con continue-as-new. Este identificador de ejecución no se expone externamente, pero puede ser útil conocerlo al depurar la ejecución de la orquestación.
Ejemplo de trabajo periódico
Un caso práctico de orquestaciones infinitas es el del código que se necesita para realizar trabajo periódico indefinidamente.
[FunctionName("Periodic_Cleanup_Loop")]
publicstaticasync Task Run(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
await context.CallActivityAsync("DoCleanup", null);
// sleep for one hour between cleanups
DateTime nextCleanup = context.CurrentUtcDateTime.AddHours(1);
await context.CreateTimer(nextCleanup, CancellationToken.None);
context.ContinueAsNew(null);
}
Nota
El ejemplo 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");
const moment = require("moment");
module.exports = df.orchestrator(function*(context) {
yield context.df.callActivity("DoCleanup");
// sleep for one hour between cleanupsconst nextCleanup = moment.utc(context.df.currentUtcDateTime).add(1, "h");
yield context.df.createTimer(nextCleanup.toDate());
yield context.df.continueAsNew(undefined);
});
Python
import azure.functions as func
import azure.durable_functions as df
from datetime import datetime, timedelta
deforchestrator_function(context: df.DurableOrchestrationContext):yield context.call_activity("DoCleanup")
# sleep for one hour between cleanups
next_cleanup = context.current_utc_datetime + timedelta(hours = 1)
yield context.create_timer(next_cleanup)
context.continue_as_new(None)
main = df.Orchestrator.create(orchestrator_function)
La diferencia entre este ejemplo y una función desencadenada por temporizador es que aquí los tiempos del desencadenador de limpieza no se basan en una programación. Por ejemplo, una programación CRON que ejecuta una función cada hora lo hará a la 1:00, 2:00, 3:00, etc. y potencialmente podría encontrarse con problemas de superposición. Sin embargo, en este ejemplo, si la limpieza tarda 30 minutos, se programará a la 1:00, 2:30, 4:00, etc., de forma que no habrá posibilidad alguna de superposición.
Inicio de una orquestación infinita
Use el método de cliente durable start-new o schedule-new para iniciar una orquestación eterna, como lo haría con cualquier otra función de orquestación.
Nota
Si debe asegurarse de que se ejecuta una orquestación infinita singleton, es importante mantener el mismo id de instancia al iniciar la orquestación. Para más información, consulte el artículo sobre la administración de instancias.
El código 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.
JavaScript
const df = require("durable-functions");
module.exports = asyncfunction (context, req) {
const client = df.getClient(context);
const instanceId = "StaticId";
// null is used as the input, since there is no input in "Periodic_Cleanup_Loop".await client.startNew("Periodic_Cleanup_Loop", instanceId, null);
context.log(`Started orchestration with ID = '${instanceId}'.`);
return client.createCheckStatusResponse(context.bindingData.req, instanceId);
};
Si en algún momento fuera necesario completar una función de orquestador, lo único que debe hacer es no llamar a ContinueAsNew y dejar que la función se cierre.
Únase a la serie de reuniones para crear soluciones de inteligencia artificial escalables basadas en casos de uso reales con compañeros desarrolladores y expertos.
Aprenda a organizar un flujo de trabajo de larga duración como un conjunto de actividades mediante instancias escalables y rentables de Durable Functions.