Temporizadores em funções duráveis (Azure Functions)

Durable Functions fornece temporizadores duráveis para uso em funções de orquestrador para implementar atrasos ou configurar tempos limite em ações assíncronas. Temporizadores duráveis devem ser usados em funções de orquestrador em vez de APIs de "suspensão" ou "atraso" que podem ser incorporadas à linguagem.

Temporizadores duráveis são tarefas que são criadas usando a API apropriada de "criar temporizador" para o idioma fornecido, conforme mostrado abaixo, e levam um tempo devido ou uma duração como argumento.

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

Quando você "aguarda" a tarefa do temporizador, a função orquestrador será suspensa até o tempo de expiração especificado.

Nota

As orquestrações continuarão a processar outros eventos de entrada enquanto aguardam a expiração de uma tarefa de temporizador.

Limitações do temporizador

Quando você cria um temporizador que expira às 16h30 UTC, o Durable Task Framework subjacente enfileira uma mensagem que se torna visível somente às 16h30 UTC. Se o aplicativo de função for reduzido para zero instâncias nesse meio tempo, a mensagem de temporizador recém-visível garantirá que o aplicativo de função seja ativado novamente em uma VM apropriada.

Nota

  • Para aplicativos JavaScript, Python e PowerShell, os temporizadores duráveis são limitados a seis dias. Para contornar essa limitação, você pode usar as APIs do temporizador em um loop para simular um while atraso maior. Aplicativos .NET e Java atualizados suportam temporizadores arbitrariamente longos.
  • Dependendo da versão do SDK e do provedor de armazenamento que está sendo usado, temporizadores longos de 6 dias ou mais podem ser implementados internamente usando uma série de temporizadores mais curtos (por exemplo, de durações de 3 dias) até que o tempo de expiração desejado seja atingido. Isso pode ser observado no armazenamento de dados subjacente, mas não afetará o comportamento de orquestração.
  • Não use APIs de data/hora internas para obter a hora atual. Ao calcular uma data futura para um temporizador expirar, sempre use a API de hora atual da função orchestrator. Para obter mais informações, consulte o artigo sobre restrições de código de função do orchestrator.

Uso para atraso

O exemplo a seguir ilustra como usar temporizadores duráveis para atrasar a execução. O exemplo é emitir uma notificação de cobrança todos os dias durante 10 dias.

[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

O exemplo anterior de C# tem como alvo Durable Functions 2.x. Para Durable Functions 1.x, você deve usar DurableOrchestrationContext em vez de IDurableOrchestrationContext. Para obter mais informações sobre as diferenças entre versões, consulte o artigo Durable Functions versions .

Aviso

Evite loops infinitos nas funções do orquestrador. Para obter informações sobre como implementar cenários de loop infinito com segurança e eficiência, consulte Orquestrações eternas.

Uso para tempo limite

Este exemplo ilustra como usar temporizadores duráveis para implementar tempos limites.

[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

O exemplo anterior de C# tem como alvo Durable Functions 2.x. Para Durable Functions 1.x, você deve usar DurableOrchestrationContext em vez de IDurableOrchestrationContext. Para obter mais informações sobre as diferenças entre versões, consulte o artigo Durable Functions versions .

Aviso

Em .NET, JavaScript, Python e PowerShell, você deve cancelar todos os temporizadores duráveis criados se seu código não esperar que eles sejam concluídos. Veja os exemplos acima para saber como cancelar temporizadores pendentes. A Estrutura de Tarefas Duráveis não alterará o status de uma orquestração para "Concluída" até que todas as tarefas pendentes, incluindo tarefas de temporizador duráveis, sejam concluídas ou canceladas.

Esse mecanismo de cancelamento usando o padrão when-any não encerra a função de atividade em andamento ou as execuções de suborquestração. Em vez disso, ele simplesmente permite que a função orquestradora ignore o resultado e siga em frente. Se o seu aplicativo de função usar o plano de consumo, você ainda será cobrado por qualquer tempo e memória consumidos pela função de atividade abandonada. Por padrão, as funções em execução no plano de consumo têm um tempo limite de cinco minutos. Se esse limite for excedido, o host do Azure Functions será reciclado para interromper toda a execução e evitar uma situação de cobrança descontrolada. O tempo limite da função é configurável.

Para obter um exemplo mais detalhado de como implementar tempos limite em funções do orquestrador, consulte o artigo Human Interaction & Timeouts - Phone Verification (Interação humana ou tempos limite - verificação por telefone).

Próximos passos