Таймеры в устойчивых функциях (Функции Azure)

Устойчивые функции предоставляют устойчивые таймеры, которые используются в функциях оркестраторов для реализации задержек или настройки времени ожидания в асинхронных действиях. Вместо API спящего режима или задержки, которые могут быть встроены в язык, в функциях оркестратора следует использовать устойчивые таймеры.

Устойчивые таймеры — это задачи, которые создаются с помощью соответствующего API создания таймера для указанного языка, как показано ниже, и в качестве аргумента принимают либо срок выполнения, либо длительность.

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

Когда вы "ожидаете" задачу таймера, функция оркестратора будет находиться в спящем режиме до указанного времени окончания срока действия.

Примечание.

Во время ожидания истечения срока действия задачи таймера оркестрации будут продолжать обрабатывать другие входящие события.

Ограничения таймера

При создании таймера, срок действия которого истекает в 16:30 (UTC), базовая платформа устойчивых задач помещает в очередь сообщение, которое становится видимым только в 16:30. Если в это время приложение-функция масштабируется до нуля экземпляров, новое отображаемое сообщение таймера обеспечит повторную активацию приложения-функции на соответствующей виртуальной машине.

Примечание.

  • Для приложений JavaScript, Python и PowerShell устойчивые таймеры ограничены шестью днями. Чтобы обойти это ограничение, можно использовать API таймера в цикле while для имитации длительной задержки. Актуальные приложения .NET и Java поддерживают произвольные длительные таймеры.
  • В зависимости от используемой версии пакета SDK и поставщика хранилища длительные таймеры в течение 6 дней или более могут быть реализованы внутри системы с помощью ряда более коротких таймеров (например, 3 дня), пока не будет достигнуто требуемое время окончания срока действия. Это можно наблюдать в базовом хранилище данных, но не влияет на поведение оркестрации.
  • Не используйте встроенные API даты и времени для получения текущего времени. При вычислении будущей даты истечения срока действия таймера всегда используйте API текущего времени функции оркестратора. Дополнительные сведения см. в статье об ограничениях кода функции оркестратора.

Использование для задержки

В следующем примере показано, как использовать устойчивые таймеры для задержки выполнения. В примере отправляется уведомление о выставлении счета каждый день в течение 10 дней.

[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");
    }
}

Примечание.

Предыдущий пример C# нацелен на Устойчивые функции 2.x. Для расширения Устойчивые функции 1.x необходимо использовать DurableOrchestrationContext вместо IDurableOrchestrationContext. Дополнительные сведения о различиях между версиями см. в статье Версии устойчивых функций.

Предупреждение

Избегайте бесконечных циклов в функциях оркестраторов. Сведения о том, как безопасно и эффективно реализовать сценарии с бесконечным циклом, см. в описании внешних оркестраций.

Использование для установки времени ожидания

В этом примере показано, как использовать устойчивые таймеры для реализации времени ожидания.

[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;
        }
    }
}

Примечание.

Предыдущий пример C# нацелен на Устойчивые функции 2.x. Для расширения Устойчивые функции 1.x необходимо использовать DurableOrchestrationContext вместо IDurableOrchestrationContext. Дополнительные сведения о различиях между версиями см. в статье Версии устойчивых функций.

Предупреждение

В .NET JavaScript, Python и PowerShell необходимо отменить созданные устойчивые таймеры, если программа не будет ожидать их завершения. В приведенных выше примерах показано, как отменить ожидающие таймеры. Платформа устойчивых задач не изменит статус оркестрации на "завершено", до тех пор, пока не будут завершены или отменены все незавершенные задачи, включая устойчивые задачи таймеров.

Этот механизм отмены на основе шаблона когда-любой не прерывает выполняющиеся действия по выполнению функций или подоркестрации. Вместо этого он просто позволяет функции оркестратора игнорировать результат и двигаться дальше. Если ваше приложение-функция использует план потребления, вам все равно будет выставлен счет за любое время и память, потребленные функцией брошенного действия. По умолчанию для функций, выполняемых в плане потребления, устанавливается время ожидания в пять минут. При превышении этого ограничения узел Функций Azure перезапускается для остановки выполнения всех процессов и предотвращения неконтролируемого выставления счетов. Время ожидания функции можно настроить.

Более подробный пример реализации тайм-аутов в функциях оркестратора см. в статье Взаимодействие с человеком и тайм-ауты — проверка по телефону.

Следующие шаги