Temporizadores en Durable Functions (Azure Functions)

Durable Functions proporciona temporizadores durables para usarlos en funciones de orquestador para implementar retrasos o configurar tiempos de expiración en acciones asincrónicas. Los temporizadores duraderos deben usarse en funciones del orquestador en lugar de api de "sleep" o "delay" que se pueden integrar en el lenguaje.

Los temporizadores duraderos son tareas que se crean mediante la API "crear temporizador" adecuada para el idioma proporcionado, como se muestra a continuación, y tardan un tiempo de vencimiento o una duración como argumento.

// Put the orchestrator to sleep for 72 hours
DateTime dueTime = context.CurrentUtcDateTime.AddHours(72);
await context.CreateTimer(dueTime, CancellationToken.None);

Cuando se "espera" la tarea del temporizador, la función del orquestador se suspenderá hasta la hora de expiración especificada.

Nota

Las orquestaciones seguirán procesando otros eventos entrantes mientras esperan que una tarea del temporizador expire.

Limitaciones de los temporizadores

Cuando se crea un temporizador que expira a las 16:30 UTC, la instancia de Durable Task Framework subyacente pone en cola un mensaje que se vuelve visible solo a las 16:30 UTC. Si la aplicación de funciones se reduce verticalmente a cero instancias mientras tanto, el mensaje del temporizador recién visible garantizará que la aplicación de funciones se active de nuevo en una máquina virtual adecuada.

Nota

  • En el caso de las aplicaciones de JavaScript, Python y PowerShell, los temporizadores duraderos están limitados a seis días. Para sortear esta limitación, puede usar las API del temporizador en un bucle whilepara simular un retraso mayor. Las aplicaciones .NET y Java actualizadas admiten temporizadores arbitrariamente largos.
  • En función de la versión del SDK y del proveedor de almacenamiento que se use, los temporizadores largos de seis días, o más, se pueden implementar internamente mediante una serie de temporizadores más cortos (por ejemplo, de tres días) hasta que se alcance la hora de expiración deseada. Esto se puede observar en el almacén de datos subyacente, pero no afectará al comportamiento de la orquestación.
  • No use la API de fecha y hora integradas para obtener la hora actual. Al calcular una fecha futura para que expire un temporizador, use siempre la API de hora actual de la función de orquestador. Para más información, consulte el artículo sobre las restricciones de código de las funciones de orquestador.

Uso para retraso

En el ejemplo siguiente se muestra cómo utilizar temporizadores durables para retrasar la ejecución. En el ejemplo se emite una notificación de facturación cada día durante 10 días.

[FunctionName("BillingIssuer")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    for (int i = 0; i < 10; i++)
    {
        DateTime deadline = context.CurrentUtcDateTime.Add(TimeSpan.FromDays(1));
        await context.CreateTimer(deadline, CancellationToken.None);
        await context.CallActivityAsync("SendBillingEvent");
    }
}

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.

Advertencia

Evite bucles infinitos en funciones de orquestador. Para más información acerca de cómo implementar de forma segura y eficaz escenarios de bucle infinito, consulte Orquestaciones infinitas.

Uso para tiempo de expiración

En este ejemplo se muestra cómo utilizar temporizadores durables para implementar tiempos de expiración.

[FunctionName("TryGetQuote")]
public static async Task<bool> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    TimeSpan timeout = TimeSpan.FromSeconds(30);
    DateTime deadline = context.CurrentUtcDateTime.Add(timeout);

    using (var cts = new CancellationTokenSource())
    {
        Task activityTask = context.CallActivityAsync("GetQuote");
        Task timeoutTask = context.CreateTimer(deadline, cts.Token);

        Task winner = await Task.WhenAny(activityTask, timeoutTask);
        if (winner == activityTask)
        {
            // success case
            cts.Cancel();
            return true;
        }
        else
        {
            // timeout case
            return false;
        }
    }
}

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.

Advertencia

En .NET, JavaScript, Python y PowerShell, debe cancelar los temporizadores duraderos creados si el código no esperará a que se completen. Consulte los ejemplos anteriores para ver cómo cancelar temporizadores pendientes. El Durable Task Framework no cambiará el estado de una orquestación a "Completado" hasta que todas las tareas pendientes, incluidas las tareas Durables con temporizador, se completen o se cancelen.

Este mecanismo de cancelación que usa el patrón when-any no termina las ejecuciones de funciones de actividad o suborquestación en curso. En su lugar, simplemente permite que la función de orquestador pase por alto el resultado y continúe. Si la aplicación de función usa el plan Consumo, se le sigue facturando por el tiempo y la memoria consumidos por la función de actividad abandonada. De manera predeterminada, las funciones en ejecución en el plan de consumo tienen un tiempo de expiración de cinco minutos. Si se supera este límite, el host de Azure Functions se recicla para detener toda la ejecución y evitar una situación de facturación descontrolada. El tiempo de expiración de la función se puede configurar.

Para obtener un ejemplo más detallado de cómo implementar tiempos de espera en funciones de orquestador, vea el artículo Las interacciones humanas en Durable Functions: comprobación telefónica de ejemplo.

Pasos siguientes