Czasomierze w rozszerzeniu Durable Functions (Azure Functions)

Rozszerzenie Durable Functions zapewnia trwałe czasomierze do użycia w funkcjach orkiestratora w celu zaimplementowania opóźnień lub skonfigurowania limitów czasu w akcjach asynchronicznych. Trwałe czasomierze powinny być używane w funkcjach orkiestratora zamiast interfejsów API "uśpienia" lub "opóźnienia", które mogą być wbudowane w język.

Trwałe czasomierze to zadania, które są tworzone przy użyciu odpowiedniego interfejsu API "tworzenia czasomierza" dla podanego języka, jak pokazano poniżej, i zajmują czas trwania lub czas trwania jako argument.

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

W przypadku zadania czasomierza "await" funkcja orkiestratora zostanie uśpiona do określonego czasu wygaśnięcia.

Uwaga

Orkiestracje będą nadal przetwarzać inne zdarzenia przychodzące podczas oczekiwania na wygaśnięcie zadania czasomierza.

Ograniczenia czasomierza

Podczas tworzenia czasomierza, który wygaśnie o godzinie 16:30 CZASU UTC, podstawowa struktura zadań Durable Task Framework zapisuje komunikat widoczny tylko o godzinie 16:30 czasu UTC. Jeśli aplikacja funkcji jest skalowana w dół do zera wystąpień w międzyczasie, nowo widoczny komunikat czasomierza zapewni, że aplikacja funkcji zostanie ponownie aktywowana na odpowiedniej maszynie wirtualnej.

Uwaga

  • W przypadku aplikacji JavaScript, Python i PowerShell czasomierze trwałe są ograniczone do sześciu dni. Aby obejść to ograniczenie, możesz użyć interfejsów API czasomierza w pętli, while aby symulować dłuższe opóźnienie. Aktualne aplikacje .NET i Java obsługują dowolnie długie czasomierze.
  • W zależności od używanej wersji zestawu SDK i dostawcy magazynu długie czasomierze z 6 dni lub więcej mogą być implementowane wewnętrznie przy użyciu serii krótszych czasomierzy (np. 3 dni trwania) do momentu osiągnięcia żądanego czasu wygaśnięcia. Można to zaobserwować w bazowym magazynie danych, ale nie wpłynie to na zachowanie orkiestracji.
  • Nie używaj wbudowanych interfejsów API daty/godziny na potrzeby pobierania bieżącej godziny. Podczas obliczania przyszłej daty wygaśnięcia czasomierza zawsze używaj bieżącego interfejsu API funkcji orkiestratora. Aby uzyskać więcej informacji, zobacz artykuł dotyczący ograniczeń kodu funkcji orkiestratora.

Użycie opóźnienia

W poniższym przykładzie pokazano, jak używać trwałych czasomierzy do opóźniania wykonywania. W tym przykładzie codziennie jest wystawiane powiadomienie rozliczeniowe przez 10 dni.

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

Uwaga

Poprzedni przykład w języku C# jest przeznaczony dla rozszerzenia Durable Functions 2.x. W przypadku rozszerzenia Durable Functions 1.x należy użyć funkcji DurableOrchestrationContextIDurableOrchestrationContextzamiast . Aby uzyskać więcej informacji na temat różnic między wersjami, zobacz artykuł Wersje rozszerzenia Durable Functions.

Ostrzeżenie

Unikaj nieskończonych pętli w funkcjach orkiestratora. Aby uzyskać informacje na temat bezpiecznego i wydajnego implementowania nieskończonych scenariuszy pętli, zobacz Eternal Orchestrations (Orkiestracje wieczne).

Użycie limitu czasu

W tym przykładzie pokazano, jak używać trwałych czasomierzy do implementowania limitów czasu.

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

Uwaga

Poprzedni przykład w języku C# jest przeznaczony dla rozszerzenia Durable Functions 2.x. W przypadku rozszerzenia Durable Functions 1.x należy użyć funkcji DurableOrchestrationContextIDurableOrchestrationContextzamiast . Aby uzyskać więcej informacji na temat różnic między wersjami, zobacz artykuł Wersje rozszerzenia Durable Functions.

Ostrzeżenie

W programach .NET, JavaScript, Python i PowerShell należy anulować wszystkie utworzone trwałe czasomierze, jeśli kod nie będzie czekać na ich ukończenie. Zapoznaj się z powyższymi przykładami, aby dowiedzieć się, jak anulować oczekujące czasomierze. Rozszerzenie Durable Task Framework nie zmieni stanu aranżacji na "Ukończono", dopóki wszystkie zaległe zadania, w tym trwałe zadania czasomierza, zostaną ukończone lub anulowane.

Ten mechanizm anulowania przy użyciu wzorca , gdy dowolny wzorzec nie kończy wykonywania działań w toku ani wykonywania orkiestracji podrzędnej. Zamiast tego po prostu umożliwia funkcji orkiestrator ignorowanie wyniku i przechodzenie dalej. Jeśli aplikacja funkcji korzysta z planu Zużycie, opłaty będą nadal naliczane za dowolny czas i pamięć zużywaną przez porzuconą funkcję działania. Domyślnie funkcje uruchomione w planie Zużycie mają limit czasu 5 minut. Jeśli ten limit zostanie przekroczony, host usługi Azure Functions zostanie odzyskany, aby zatrzymać wszystkie wykonywanie i zapobiec sytuacji rozliczeniowej ucieczki. Limit czasu funkcji można skonfigurować.

Aby uzyskać bardziej szczegółowy przykład implementacji limitów czasu w funkcjach orkiestratora, zobacz artykuł Human Interaction & Timeouts — Telefon Weryfikacja.

Następne kroki