Wieczne orkiestracje

Orkiestracje wieczne to funkcje orkiestratora, które działają bezterminowo, okresowo resetując własną historię za pomocą continue-as-new API. Są one przydatne w przypadku agregatorów, okresowych zadań w tle i dowolnego scenariusza Durable Functions, który wymaga nieskończonej pętli bez nieograniczonego wzrostu historii.

Bez continue-as-neworkiestratora, który działa w nieskończonej pętli, gromadzącego z każdą zaplanowaną operacją historię orkiestracji, ostatecznie dochodzi do problemów z wydajnością i nadmiernego użycia pamięci. Wieczny wzorzec aranżacji rozwiązuje ten problem, resetując historię w każdej iteracji.

Uwaga / Notatka

Przykłady kodu dla trwałej orkiestracji są dostępne dla języków C#, JavaScript, Python i Java. Program PowerShell nie obsługuje continue-as-new.

W tym artykule:

Orkiestracje wieczne to orkiestracje, które działają bezterminowo, okresowo resetując swoją historię przy użyciu interfejsu continue-as-new API. Są one przydatne w agregatorach, okresowych zadaniach w tle i każdym scenariuszu, który wymaga nieskończonej pętli bez niekontrolowanego rozrostu historii.

Bez continue-as-new orkiestracji, która zapętla się w nieskończoność i gromadzi historię przy każdym zaplanowanym zadaniu, w końcu powoduje problemy z wydajnością i zbyt duże zużycie pamięci. Wieczny wzorzec aranżacji rozwiązuje ten problem, resetując historię w każdej iteracji.

Ważna

Obecnie zestaw POWERShell Durable Task SDK nie jest dostępny.

W tym artykule:

Jak działa kontynuacja zgodnie z nowym działaniem

Zamiast używać nieskończonych pętli, funkcje orkiestratora resetują swój stan, wywołując metodę continue-as-newpowiązania wyzwalacza orkiestracji. Ta metoda przyjmuje parametr z możliwością serializacji JSON, który staje się nowym wejściem dla następnej generacji funkcji orkiestratora.

Po wywołaniu continue-as-new wystąpienie orkiestracji restartuje się z nową wartością wejściową. Ten sam identyfikator wystąpienia jest zachowywany, ale historia funkcji orkiestratora jest resetowana.

Zamiast używać nieskończonych pętli, orkiestracje resetują swój stan, wywołując metodę continue-as-new w kontekście aranżacji. Ta metoda przyjmuje parametr z możliwością serializacji JSON, który staje się nowym wejściem dla następnej generacji aranżacji.

Po wywołaniu continue-as-new wystąpienie orkiestracji restartuje się z nową wartością wejściową. Ten sam identyfikator wystąpienia jest zachowywany, ale historia orkiestracji jest resetowana.

Zagadnienia dotyczące orkiestracji wiecznej

Podczas używania continue-as-new metody w aranżacji należy pamiętać o następujących kwestiach:

  • Gdy funkcja orkiestratora zostanie zresetowana przy użyciu metody continue-as-new, Durable Task Framework zachowuje ten sam identyfikator wystąpienia, ale wewnętrznie tworzy i używa nowego identyfikatora wykonania na przyszłość. Ten identyfikator uruchomienia nie jest udostępniony zewnętrznie, ale jest przydatny podczas debugowania wykonywania orkiestracji.

  • Gdy podczas wykonywania wystąpi nieobsługiwany wyjątek, orkiestracja przechodzi w stan niepowodzenia i kończy wykonywanie. Wywołanie metody continue-as-new z finally bloku nie powoduje ponownego uruchomienia aranżacji po wystąpieniu wyjątku nieuchwyconego.

  • Wyniki wszystkich niekompletnych zadań są odrzucane, gdy orkiestracja wywołuje continue-as-new. Jeśli na przykład czasomierz jest zaplanowany, a następnie continue-as-new zostanie wywołany przed uruchomieniem czasomierza, zdarzenie czasomierza zostanie odrzucone.

  • Opcjonalnie można zachować nieprzetworzone zdarzenia zewnętrzne podczas continue-as-new ponownych uruchomień. W języku C# ContinueAsNew domyślnie zachowuje nieprzetworzone zdarzenia. W Java continueAsNew również domyślnie zachowuje zdarzenia. W Python continue_as_new nie zachowuje zdarzeń, chyba że save_events=True. W języku JavaScript continueAsNew wymaga parametru saveEvents (true lub false) w celu kontrolowania tego zachowania.

Podczas używania continue-as-new metody w aranżacji należy pamiętać o następujących kwestiach:

  • Gdy orkiestracja zostanie zresetowana przy użyciu metody continue-as-new, zestawy SDK zadań trwałych zachowują ten sam identyfikator wystąpienia, ale wewnętrznie tworzą i używają nowego identyfikatora wykonania na przyszłość. Ten identyfikator wykonania nie jest widoczny zewnętrznie, ale może być przydatny podczas debugowania procesów orkiestracyjnych.

  • Gdy podczas wykonywania wystąpi nieobsługiwany wyjątek, orkiestracja przechodzi w stan niepowodzenia i kończy wykonywanie. Wywołanie metody continue-as-new z finally bloku nie powoduje ponownego uruchomienia orkiestracji po wystąpieniu nieuchwyconego wyjątku.

  • Wyniki wszystkich niekompletnych zadań są odrzucane, gdy orkiestracja wywołuje continue-as-new. Jeśli na przykład czasomierz jest zaplanowany, a następnie continue-as-new zostanie wywołany przed uruchomieniem czasomierza, zdarzenie czasomierza zostanie odrzucone.

  • Opcjonalnie można zachować nieprzetworzone zdarzenia zewnętrzne podczas continue-as-new ponownych uruchomień. W .NET i Java continue-as-new domyślnie zachowuje nieprzetworzone zdarzenia. W Python continue_as_new nie zachowuje zdarzeń, chyba że save_events=True. W języku JavaScript continueAsNew wymaga parametru saveEvents (true lub false) w celu kontrolowania tego zachowania. We wszystkich przypadkach nieprzetworzone zdarzenia są dostarczane, gdy orkiestracja następnie wywołuje waitForExternalEvent lub wait_for_external_event.

Przykład pracy okresowej

Jednym z typowych przypadków użycia trwałych orkiestracji jest okresowa praca w tle, taka jak zadania czyszczące.

Dlaczego nie używać wyzwalacza czasomierza? Wyzwalacz czasomierza oparty na CRON jest uruchamiany w stałych godzinach niezależnie od tego, czy poprzednie uruchomienie zostało zakończone. Wieczna orkiestracja czeka na ukończenie operacji przed zaplanowaniem następnej iteracji, więc operacje nigdy się nie nakładają.

Approach Harmonogram (1-godzinny interwał, 30-minutowe zadanie) Nakładanie się ryzyka
Wyzwalacz czasomierza (CRON) 1:00, 2:00, 3:00 Tak — jeśli zadanie przekracza interwał
Wieczna orkiestracja 1:00, 2:30, 4:00 Nie — następne uruchomienie czeka na ukończenie
[FunctionName("Periodic_Cleanup_Loop")]
public static async 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);
}
public class PeriodicCleanupLoop : TaskOrchestrator<object?, object?>
{
    public override async Task<object?> RunAsync(TaskOrchestrationContext context, object? input)
    {
        await context.CallActivityAsync("DoCleanup");

        // sleep for one hour between cleanups
        await context.CreateTimer(TimeSpan.FromHours(1), CancellationToken.None);

        context.ContinueAsNew(null);
        return null;
    }
}

Rozpoczynanie wiecznej aranżacji

Użyj metody start-new klienta trwałego lub schedule-new, aby rozpocząć wieczną orkiestrację, podobnie jak każdą inną funkcję orkiestracji. Aby zapewnić, że tylko jedno wystąpienie jest uruchamiane w danym momencie, użyj stałego identyfikatora wystąpienia. Aby uzyskać więcej informacji, zobacz Orkiestracje Singleton.

[FunctionName("Trigger_Eternal_Orchestration")]
public static async Task<HttpResponseMessage> OrchestrationTrigger(
    [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage request,
    [DurableClient] IDurableOrchestrationClient client)
{
    string instanceId = "StaticId";

    await client.StartNewAsync("Periodic_Cleanup_Loop", instanceId); 
    return client.CreateCheckStatusResponse(request, instanceId);
}

Użyj metody client schedule-new, aby rozpocząć nieskończoną orkiestrację, podobnie jak w przypadku każdej innej orkiestracji. Aby zapewnić, że tylko jedno wystąpienie jest uruchamiane w danym momencie, użyj stałego identyfikatora wystąpienia. Aby uzyskać więcej informacji, zobacz Singleton orchestrations.

string instanceId = "StaticId";
await client.ScheduleNewOrchestrationInstanceAsync(
    "PeriodicCleanupLoop",
    null,
    new StartOrchestrationOptions { InstanceId = instanceId });

Wyjście z wiecznej orkiestracji

Jeśli funkcja orkiestratora musi ostatecznie się zakończyć, nie wykonuj continue-as-new i pozwól funkcji się zakończyć.

Jeśli funkcja orkiestratora znajduje się w nieskończonej pętli i musi zostać zatrzymana, użyj interfejsu API terminate powiązania klienta orkiestracji , aby go zatrzymać.

await client.TerminateAsync(instanceId, "Cleanup no longer needed");

Aby uzyskać więcej informacji, zobacz Zarządzanie wystąpieniami.

Jeśli orkiestracja musi ostatecznie się zakończyć, nie wywołuj metody continue-as-new i pozwól, aby orkiestracja się zakończyła.

Jeśli orkiestracja znajduje się w nieskończonej pętli i musi zostać zatrzymana, użyj interfejsu API terminate na kliencie zadań Durable, aby ją zatrzymać.

await client.TerminateInstanceAsync(instanceId, "Cleanup no longer needed");

Następne kroki