Ewige Orchestrierung

Ewige Orchestrierungen sind Orchestratorfunktionen, die unbegrenzt ausgeführt werden, indem sie ihren eigenen Verlauf mithilfe der continue-as-new API regelmäßig zurücksetzen. Sie sind nützlich für Aggregatoren, regelmäßige Hintergrundaufträge und jedes Durable Functions-Szenario, das eine endlose Schleife ohne unbegrenztes Verlaufswachstum erfordert.

Ohne continue-as-new würde ein Orchestrator, der sich in einer Endlosschleife befindet, mit jeder geplanten Aufgabe den Orchestrierungsverlauf ansammeln, was schließlich Leistungsprobleme und eine übermäßige Nutzung des Arbeitsspeichers verursachen würde. Das ewige Orchestrierungsmuster löst dies, indem die Geschichte bei jeder Iteration zurückgesetzt wird.

Hinweis

Ewige Orchestrierungscodebeispiele sind für C#, JavaScript, Python und Java verfügbar. PowerShell unterstützt continue-as-newnicht .

In diesem Artikel:

Ewige Orchestrierungen sind Orchestrierungen , die unbegrenzt ausgeführt werden, indem sie ihren eigenen Verlauf mithilfe der continue-as-new API regelmäßig zurücksetzen. Sie sind nützlich für Aggregatoren, regelmäßige Hintergrundaufträge und jedes Szenario, das eine endlose Schleife ohne ungebundenes Verlaufswachstum erfordert.

Ohne continue-as-new würde eine Orchestrierung, die sich endlos wiederholt, mit jedem geplanten Vorgang Verlauf ansammeln, was schließlich Leistungsprobleme und übermäßige Speichernutzung verursacht. Das ewige Orchestrierungsmuster löst dies, indem die Geschichte bei jeder Iteration zurückgesetzt wird.

Von Bedeutung

Derzeit ist das PowerShell Durable Task SDK nicht verfügbar.

In diesem Artikel:

Wie "Fortfahren als Neu" funktioniert

Anstatt Endlosschleifen zu verwenden, setzen Orchestratorfunktionen ihren Status zurück, indem sie die Methode continue-as-new in der Orchestrierungstriggerbindung aufrufen. Diese Methode verwendet einen JSON-serialisierbaren Parameter, der zur neuen Eingabe für die nächste Orchestratorfunktionsgenerierung wird.

Beim Aufrufen continue-as-newwird die Orchestrierungsinstanz mit dem neuen Eingabewert neu gestartet. Die gleiche Instanz-ID wird beibehalten, aber der Verlauf der Orchestratorfunktion wird zurückgesetzt.

Anstatt Endlosschleifen zu verwenden, setzen Orchestrierungen ihren Zustand zurück, indem sie die continue-as-new-Methode für den Orchestrierungskontext aufrufen. Diese Methode verwendet einen JSON-serialisierbaren Parameter, der zur neuen Eingabe für die nächste Orchestrierungsgenerierung wird.

Beim Aufrufen continue-as-newwird die Orchestrierungsinstanz mit dem neuen Eingabewert neu gestartet. Es wird dieselbe Instanz-ID beibehalten, aber der Verlauf der Orchestrierung wird zurückgesetzt.

Überlegungen zur ewigen Orchestrierung

Beachten Sie diese Überlegungen bei der Verwendung der continue-as-new Methode in einer Orchestrierung:

  • Wenn eine Orchestratorfunktion mithilfe der continue-as-new Methode zurückgesetzt wird, verwaltet das Durable Task Framework dieselbe Instanz-ID, erstellt aber intern eine neue Ausführungs-ID und verwendet diese. Diese Ausführungs-ID wird nicht extern verfügbar gemacht, ist aber beim Debuggen der Orchestrierungsausführung hilfreich.

  • Wenn während der Ausführung eine unbehandelte Ausnahme auftritt, tritt die Orchestrierung in einen fehlerhaften Zustand ein, und die Ausführung wird beendet. Ein Aufruf von continue-as-new aus einem finally-Block startet die Orchestrierung nach einer nicht abgefangenen Ausnahme nicht neu.

  • Die Ergebnisse unvollständiger Aufgaben werden verworfen, wenn eine Orchestrierung continue-as-new aufruft. Wenn beispielsweise ein Timer geplant ist und dann continue-as-new aufgerufen wird, bevor der Timer ausgelöst wird, wird das Timer-Ereignis verworfen.

  • Optionalerweise können Sie unverarbeitete externe Ereignisse über continue-as-new Neustarts hinweg beibehalten. In C# ContinueAsNew bleiben unverarbeitete Ereignisse standardmäßig erhalten. In Java behält continueAsNew ereignisse standardmäßig bei. In Python behält continue_as_new keine Ereignisse bei, es sei denn, save_events=True. In JavaScript ist ein continueAsNew Parameter (saveEvents entweder true oder false) erforderlich, um dieses Verhalten zu steuern.

Beachten Sie diese Überlegungen bei der Verwendung der continue-as-new Methode in einer Orchestrierung:

  • Wenn eine Orchestrierung mit der continue-as-new-Methode zurückgesetzt wird, behalten die Durable Task-SDKs dieselbe Instanz-ID bei, erstellen aber intern eine neue Ausführungs-ID. Diese Ausführungs-ID wird nicht extern verfügbar gemacht, kann aber beim Debuggen der Orchestrierungsausführung hilfreich sein.

  • Wenn während der Ausführung eine unbehandelte Ausnahme auftritt, tritt die Orchestrierung in einen fehlerhaften Zustand ein, und die Ausführung wird beendet. Ein Aufruf continue-as-new aus einem finally Block heraus startet die Orchestrierung nach einer nicht abgefangenen Ausnahme nicht neu.

  • Die Ergebnisse unvollständiger Aufgaben werden verworfen, wenn eine Orchestrierung continue-as-new aufruft. Wenn beispielsweise ein Timer geplant ist und dann continue-as-new aufgerufen wird, bevor der Timer ausgelöst wird, wird das Timer-Ereignis verworfen.

  • Optionalerweise können Sie unverarbeitete externe Ereignisse über continue-as-new Neustarts hinweg beibehalten. In .NET und Java behält continue-as-new standardmäßig nicht verarbeitete Ereignisse bei. In Python behält continue_as_new keine Ereignisse bei, es sei denn, save_events=True. In JavaScript ist ein continueAsNew Parameter (saveEvents entweder true oder false) erforderlich, um dieses Verhalten zu steuern. In allen Fällen werden unverarbeitete Ereignisse ausgeliefert, wenn die Orchestrierung das nächste Mal waitForExternalEvent oder wait_for_external_event aufruft.

Beispiel für regelmäßige Arbeit

Ein gängiger Anwendungsfall für dauerhafte Orchestrierungen ist periodische Hintergrundtätigkeiten, z. B. Bereinigungsaufträge.

Warum wird kein Timertrigger verwendet? Ein CRON-basierter Timertrigger wird zu festen Zeiten ausgeführt, unabhängig davon, ob die vorherige Ausführung abgeschlossen ist. Eine dauerhafte Orchestrierung wartet, bis die Arbeit abgeschlossen ist, bevor die nächste Iteration geplant wird, damit keine Überschneidungen auftreten.

Approach Zeitplan (1-Stunden-Intervall, 30-Minuten-Auftrag) Überlappungsrisiko
Zeitgeber-Trigger (CRON) 1:00, 2:00, 3:00 Ja – wenn der Auftrag das Intervall überschreitet
Ewige Orchestrierung 1:00, 2:30, 4:00 Nein – nächste Ausführung wartet auf den Abschluss
[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;
    }
}

Beginnen Sie einen ewigen Prozess der Orchestrierung

Verwenden Sie die Methode start-new oder schedule-new, um eine dauerhafte Orchestrierung wie jede andere Orchestrierungsfunktion zu starten. Um sicherzustellen, dass jeweils nur eine Instanz ausgeführt wird, verwenden Sie eine feste Instanz-ID. Weitere Informationen finden Sie unter Singleton-Orchestrierungen.

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

Verwenden Sie die client-Methode 'schedule-new', um eine endlose Orchestrierung wie jede andere Orchestrierung zu starten. Um sicherzustellen, dass jeweils nur eine Instanz ausgeführt wird, verwenden Sie eine feste Instanz-ID. Weitere Informationen finden Sie unter Singleton-Orchestrierungen.

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

Austritt aus einer ewigen Orchestrierung

Wenn eine Orchestratorfunktion schließlich abgeschlossen werden muss, rufen Sie continue-as-new nicht auf und lassen Sie die Funktion einfach enden.

Wenn sich eine Orchestratorfunktion in einer Endlosschleife befindet und beendet werden muss, verwenden Sie die Beendigungs-API der Orchestrierungsclientbindung, um sie zu beenden.

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

Weitere Informationen finden Sie unter Instanzverwaltung.

Wenn eine Orchestrierung schließlich abgeschlossen werden muss, rufen Sie nicht continue-as-new auf und lassen Sie zu, dass die Orchestrierung beendet wird.

Wenn sich eine Orchestrierung in einer Endlosschleife befindet und beendet werden muss, verwenden Sie die Beenden-API auf dem Client für dauerhafte Aufgaben, um diese zu beenden.

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

Nächste Schritte