Verwalten von Instanzen in Durable Functions in Azure

Orchestrierungen in Durable Functions sind zeitintensive zustandsbehaftete Funktionen, die mithilfe integrierter Verwaltungs-APIs gestartet, abgefragt, angehalten, fortgesetzt und beendet werden können. Auch einige andere Instanzverwaltungs-APIs werden durch die Orchestrierungsclientbindung von Durable Functions verfügbar gemacht, zum Beispiel das Senden externer Ereignisse an Instanzen oder das Löschen des Instanzverlaufs. In diesem Artikel werden alle unterstützten Instanzverwaltungsvorgänge detailliert erläutert.

Starten von Instanzen

Die Methode start-new (oder schedule-new) der Bindung des Orchestrierungsclients startet eine neue Orchestrierungsinstanz. Intern schreibt diese Methode eine Meldung über den Durable Functions-Speicheranbieter und wird dann zurückgegeben. Diese Meldung löst asynchron die Ausführung der Orchestrierungsfunktion aus, deren Namen angegeben wurde.

Die Parameter zum Starten einer neuen Orchestrierungsinstanz lauten wie folgt:

  • Name: Der Name der zu planenden Orchestratorfunktion.
  • Eingabe: Alle JSON-serialisierbaren Daten, die als Eingabe an die Orchestratorfunktion übergeben werden sollen.
  • InstanceId: (Optional) Die eindeutige ID der Instanz. Ohne Angabe dieses Parameters verwendet die Methode eine zufällige ID.

Tipp

Verwenden Sie nach Möglichkeit einen zufälligen Bezeichner für die Instanz-ID. Zufällige Instanz-IDs gewährleisten eine gleichmäßige Lastenverteilung, wenn Sie Orchestratorfunktionen über mehrere virtuelle Computer hinweg skalieren. Wenn die ID aus einer externen Quelle stammen muss oder bei der Implementierung des Singleton-Orchestrator-Musters sollten Sie nicht zufällige Instanz-IDs verwenden.

Der folgende Code ist eine Beispielfunktion, die eine neue Orchestrierungsinstanz startet:

[FunctionName("HelloWorldQueueTrigger")]
public static async Task Run(
    [QueueTrigger("start-queue")] string input,
    [DurableClient] IDurableOrchestrationClient starter,
    ILogger log)
{
    string instanceId = await starter.StartNewAsync("HelloWorld", input);
    log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
}

Hinweis

Der vorherige C#-Code ist für Durable Functions 2.x vorgesehen. Für Durable Functions 1.x müssen Sie das OrchestrationClient-Attribut anstelle des DurableClient-Attributs verwenden, und Sie müssen den DurableOrchestrationClient-Parametertyp anstelle von IDurableOrchestrationClient verwenden. Weitere Informationen zu den Unterschieden zwischen den Versionen finden Sie im Artikel Durable Functions-Versionen.

Azure Functions Core Tools

Sie können eine Instanz auch direkt starten, indem Sie den func durable start-new-Befehl in den Core Tools verwenden, der die folgenden Parameter annimmt:

  • function-name (erforderlich) : Der Name der zu startenden Funktion.
  • input (optional) : Die Eingabe für die Funktion, entweder inline oder über eine JSON-Datei. Fügen Sie bei Dateien dem Pfad zur Datei mit @ ein Präfix hinzu, z.B. @path/to/file.json.
  • id (optional) : Die ID der Orchestrierungsinstanz. Ohne Angabe dieses Parameters verwendet der Befehl eine zufällige ID.
  • connection-string-setting (optional) : Der Name der Anwendungseinstellung mit der zu verwendenden Speicherverbindungszeichenfolge. Der Standardwert ist AzureWebJobsStorage.
  • task-hub-name (optional) : Der Name des zu verwendenden Durable Functions-Aufgabenhubs. Der Standardwert ist DurableFunctionsHub. Sie können diesen Wert auch über „durableTask:HubName“ in host.json festlegen.

Hinweis

Bei Core Tools-Befehlen wird davon ausgegangen, dass Sie sie im Stammverzeichnis einer Funktions-App ausführen. Wenn Sie den connection-string-setting- und task-hub-name-Parameter explizit angeben, können Sie die Befehle von jedem beliebigen Verzeichnis aus ausführen. Sie können diese Befehle zwar ausführen, ohne dass ein Funktions-App-Host ausgeführt wird, aber möglicherweise stellen Sie fest, dass Sie einige Auswirkungen nur dann beobachten können, wenn der Host ausgeführt wird. Beispielsweise reiht der Befehl start-new eine Startmeldung in die Warteschlange für den Zielaufgabenhub ein, die Orchestrierung wird jedoch nicht ausgeführt, bis ein Funktions-App-Hostprozess ausgeführt wird, der die Nachricht verarbeiten kann.

Hinweis

Core Tools-Befehle werden derzeit nur unterstützt, wenn der Azure Storage-Standardanbieter zum Beibehalten des Runtimestatus verwendet wird.

Der folgende Befehl startet die Funktion HelloWorld und übergibt dieser den Inhalt der Datei counter-data.json:

func durable start-new --function-name HelloWorld --input @counter-data.json --task-hub-name TestTaskHub

Abfragen von Instanzen

Nach dem Starten neuer Orchestrierungsinstanzen müssen Sie wahrscheinlich deren Runtimestatus abfragen, um zu ermitteln, ob diese derzeit ausgeführt werden, erfolgreich ausgeführt wurden oder ein Fehler aufgetreten ist.

Die Methodeget-status der Orchestrierungsclientbindung fragt den Status einer Orchestrierungsinstanz ab.

Hierfür werden instanceId (erforderlich), showHistory (optional), showHistoryOutput (optional) und showInput (optional) als Parameter verwendet.

  • showHistory : Bei Festlegung auf true enthält die Antwort den Ausführungsverlauf.
  • showHistoryOutput : Bei Festlegung auf true enthält der Ausführungsverlauf Aktivitätsausgaben.
  • showInput : Bei Festlegung auf false enthält die Antwort nicht die Eingabe der Funktion. Standardwert: true.

Die Methode gibt ein Objekt mit den folgenden Eigenschaften zurück:

  • Name: Der Name der Orchestratorfunktion.
  • InstanceId: Die Instanz-ID der Orchestrierung (muss mit der Eingabe instanceId identisch sein).
  • CreatedTime: Der Zeitpunkt, zu dem die Ausführung der Orchestratorfunktion gestartet wurde.
  • LastUpdatedTime: Der Zeitpunkt, zu dem der letzte Prüfpunkt für die Orchestrierung erstellt wurde.
  • Eingabe: Die Eingabe der Funktion als JSON-Wert. Dieses Feld wird nicht aufgefüllt, wenn showInput FALSE ist.
  • CustomStatus: Der benutzerdefinierter Orchestrierungsstatus im JSON-Format.
  • Ausgabe: Die Ausgabe der Funktion als JSON-Wert (wenn die Funktion abgeschlossen wurde). Wenn ein Fehler bei der Orchestratorfunktion auftritt, enthält diese Eigenschaft die Fehlerdetails. Wenn die Orchestratorfunktion angehalten oder beendet wurde, enthält diese Eigenschaft den Grund für das Anhalten oder die Beendigung (sofern vorhanden).
  • RuntimeStatus: Einer der folgenden Werte:
    • Pending: Die Instanz wurde geplant, ihre Ausführung aber noch nicht gestartet.
    • Wird ausgeführt: Die Instanz wurde gestartet.
    • Completed: Die Instanz wurde normal abgeschlossen.
    • ContinuedAsNew: Die Instanz hat sich selbst mit einem neuen Verlauf neu gestartet. Der Status ist ein vorübergehender Status.
    • Fehler: Bei der Instanz ist ein Fehler aufgetreten.
    • Beendet: Die Instanz wurde plötzlich beendet.
    • Angehalten: Die Instanz wurde angehalten und kann zu einem späteren Zeitpunkt fortgesetzt werden.
  • History: Der Ausführungsverlauf der Orchestrierung. Dieses Feld wird nur gefüllt, wenn showHistory auf true festgelegt ist.

Hinweis

Ein Orchestrator wird erst mit Completed gekennzeichnet, wenn alle seine geplanten Aufgaben abgeschlossen wurden und der Orchestrator die Anweisung zum Zurückgeben ausgeführt hat. Das bedeutet, es reicht nicht aus, dass ein Orchestrator seine return-Anweisung erreicht, damit er mit Completed gekennzeichnet wird. Dies ist insbesondere in Fällen relevant, in denen WhenAny verwendet wird. Diese Orchestratoren führen oft die return-Anweisung aus, bevor alle geplanten Aufgaben durchgeführt wurden.

Diese Methode gibt null (.NET und Java), undefined (JavaScript) oder None (Python) zurück, wenn die Instanz nicht vorhanden ist.

[FunctionName("GetStatus")]
public static async Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("check-status-queue")] string instanceId)
{
    DurableOrchestrationStatus status = await client.GetStatusAsync(instanceId);
    // do something based on the current status.
}

Hinweis

Der vorherige C#-Code ist für Durable Functions 2.x vorgesehen. Für Durable Functions 1.x müssen Sie das OrchestrationClient-Attribut anstelle des DurableClient-Attributs verwenden, und Sie müssen den DurableOrchestrationClient-Parametertyp anstelle von IDurableOrchestrationClient verwenden. Weitere Informationen zu den Unterschieden zwischen den Versionen finden Sie im Artikel Durable Functions-Versionen.

Azure Functions Core Tools

Es ist auch möglich, den Status der Orchestrierung direkt über den func durable get-runtime-status-Befehl in den Core Tools abzurufen.

Hinweis

Core Tools-Befehle werden derzeit nur unterstützt, wenn der Azure Storage-Standardanbieter zum persistenten Speichern des Runtimestatus verwendet wird.

Für den Befehl durable get-runtime-status werden die folgenden Parameter verwendet:

  • id (erforderlich) : Die ID der Orchestrierungsinstanz.
  • show-input (optional) : Bei Festlegung auf true enthält die Antwort die Eingabe der Funktion. Standardwert: false.
  • show-output (optional) : Bei Festlegung auf true enthält die Antwort die Ausgabe der Funktion. Standardwert: false.
  • connection-string-setting (optional) : Der Name der Anwendungseinstellung mit der zu verwendenden Speicherverbindungszeichenfolge. Der Standardwert lautet AzureWebJobsStorage.
  • task-hub-name (optional) : Der Name des zu verwendenden Durable Functions-Aufgabenhubs. Der Standardwert lautet DurableFunctionsHub. Der Wert kann auch über „durableTask:HubName“ in host.json festgelegt werden.

Der folgende Befehl ruft den Status (einschließlich Ein- und Ausgaben) einer Instanz mit der Orchestrierungsinstanz-ID 0ab8c55a66644d68a3a8b220b12d209c ab. Dabei wird vorausgesetzt, dass Sie den Befehl func im Stammverzeichnis der Funktions-App ausführen:

func durable get-runtime-status --id 0ab8c55a66644d68a3a8b220b12d209c --show-input true --show-output true

Sie können den Befehl durable get-history zum Abrufen des Ausführungsverlaufs einer Orchestrierungsinstanz verwenden. Hierfür werden die folgenden Parameter verwendet:

  • id (erforderlich) : Die ID der Orchestrierungsinstanz.
  • connection-string-setting (optional) : Der Name der Anwendungseinstellung mit der zu verwendenden Speicherverbindungszeichenfolge. Der Standardwert lautet AzureWebJobsStorage.
  • task-hub-name (optional) : Der Name des zu verwendenden Durable Functions-Aufgabenhubs. Der Standardwert lautet DurableFunctionsHub. Der Wert kann auch über „durableTask:HubName“ in „host.json“ festgelegt werden.
func durable get-history --id 0ab8c55a66644d68a3a8b220b12d209c

Abfragen aller Instanzen

Sie können die APIs in Ihrem Sprach-SDK verwenden, um den Status aller Orchestrierungsinstanzen in Ihrem Aufgabenhub abzufragen. Diese list-instances- oder get-status-API gibt eine Liste von Objekten zurück, die die Orchestrierungsinstanzen repräsentieren, die den Abfrageparametern entsprechen.

[FunctionName("GetAllStatus")]
public static async Task Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient client,
    ILogger log)
{
    var noFilter = new OrchestrationStatusQueryCondition();
    OrchestrationStatusQueryResult result = await client.ListInstancesAsync(
        noFilter,
        CancellationToken.None);
    foreach (DurableOrchestrationStatus instance in result.DurableOrchestrationState)
    {
        log.LogInformation(JsonConvert.SerializeObject(instance));
    }
    
    // Note: ListInstancesAsync only returns the first page of results.
    // To request additional pages provide the result.ContinuationToken
    // to the OrchestrationStatusQueryCondition's ContinuationToken property.
}

Hinweis

Der vorherige C#-Code ist für Durable Functions 2.x vorgesehen. Für Durable Functions 1.x müssen Sie das OrchestrationClient-Attribut anstelle des DurableClient-Attributs verwenden, und Sie müssen den DurableOrchestrationClient-Parametertyp anstelle von IDurableOrchestrationClient verwenden. Weitere Informationen zu den Unterschieden zwischen den Versionen finden Sie im Artikel Durable Functions-Versionen.

Azure Functions Core Tools

Es ist auch möglich, Instanzen direkt abzufragen, indem Sie den func durable get-instances-Befehl in den Core Tools verwenden.

Hinweis

Core Tools-Befehle werden derzeit nur unterstützt, wenn der Azure Storage-Standardanbieter zum Beibehalten des Runtimestatus verwendet wird.

Für den Befehl durable get-instances werden die folgenden Parameter verwendet:

  • top (optional) : Dieser Befehl unterstützt Paging. Dieser Parameter entspricht der Anzahl der pro Anforderung abgerufenen Instanzen. Der Standardwert ist 10.
  • continuation-token (optional) : Ein Token, das angibt, welche Seite oder welcher Abschnitt der Instanzen abgerufen werden soll. Jede Ausführung von get-instances gibt ein Token an den nächsten Satz von Instanzen zurück.
  • connection-string-setting (optional) : Der Name der Anwendungseinstellung mit der zu verwendenden Speicherverbindungszeichenfolge. Der Standardwert lautet AzureWebJobsStorage.
  • task-hub-name (optional) : Der Name des zu verwendenden Durable Functions-Aufgabenhubs. Der Standardwert lautet DurableFunctionsHub. Der Wert kann auch über „durableTask:HubName“ in host.json festgelegt werden.
func durable get-instances

Abfragen von Instanzen mit Filtern

Was ist, wenn Sie nicht alle Informationen benötigen, die eine standardmäßige Instanzenabfrage bieten kann? Wenn Sie z.B. nur den Zeitpunkt der Erstellung der Orchestrierung oder den Laufzeitstatus der Orchestrierung erfahren möchten? Sie können die Abfrage durch Anwenden von Filtern eingrenzen.

[FunctionName("QueryStatus")]
public static async Task Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient client,
    ILogger log)
{
    // Get the first 100 running or pending instances that were created between 7 and 1 day(s) ago
    var queryFilter = new OrchestrationStatusQueryCondition
    {
        RuntimeStatus = new[]
        {
            OrchestrationRuntimeStatus.Pending,
            OrchestrationRuntimeStatus.Running,
        },
        CreatedTimeFrom = DateTime.UtcNow.Subtract(TimeSpan.FromDays(7)),
        CreatedTimeTo = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)),
        PageSize = 100,
    };
    
    OrchestrationStatusQueryResult result = await client.ListInstancesAsync(
        queryFilter,
        CancellationToken.None);
    foreach (DurableOrchestrationStatus instance in result.DurableOrchestrationState)
    {
        log.LogInformation(JsonConvert.SerializeObject(instance));
    }
}

Hinweis

Der vorherige C#-Code ist für Durable Functions 2.x vorgesehen. Für Durable Functions 1.x müssen Sie das OrchestrationClient-Attribut anstelle des DurableClient-Attributs verwenden, und Sie müssen den DurableOrchestrationClient-Parametertyp anstelle von IDurableOrchestrationClient verwenden. Weitere Informationen zu den Unterschieden zwischen den Versionen finden Sie im Artikel Durable Functions-Versionen.

Azure Functions Core Tools

In den Azure Functions Core Tools können Sie auch den Befehl durable get-instances mit Filtern verwenden. Zusätzlich zu den oben genannten Parametern top, continuation-token, connection-string-setting und task-hub-name können Sie drei Filterparameter (created-after, created-before und runtime-status) verwenden.

Hinweis

Core Tools-Befehle werden derzeit nur unterstützt, wenn der Azure Storage-Standardanbieter zum Beibehalten des Runtimestatus verwendet wird.

Im Folgenden sind die Parameter für den Befehl durable get-instances angegeben.

  • created-after (optional) : Ruft die nach diesem Datum/dieser Uhrzeit (UTC) erstellten Instanzen ab. Es werden nach ISO 8601 formatierte datetime-Werte akzeptiert.
  • created-before (optional) : Ruft die vor diesem Datum/dieser Uhrzeit (UTC) erstellten Instanzen ab. Es werden nach ISO 8601 formatierte datetime-Werte akzeptiert.
  • runtime-status (optional) : Rufen Sie die Instanzen mit einem bestimmten Status ab (z.B. „Ausgeführt“ oder „Abgeschlossen“). Es können mehrere Status angegeben werden (Leerzeichen als Trennzeichen).
  • top (optional) : Die Anzahl pro Anforderung abgerufener Instanzen. Der Standardwert ist 10.
  • continuation-token (optional) : Ein Token, das angibt, welche Seite oder welcher Abschnitt der Instanzen abgerufen werden soll. Jede Ausführung von get-instances gibt ein Token an den nächsten Satz von Instanzen zurück.
  • connection-string-setting (optional) : Der Name der Anwendungseinstellung mit der zu verwendenden Speicherverbindungszeichenfolge. Der Standardwert lautet AzureWebJobsStorage.
  • task-hub-name (optional) : Der Name des zu verwendenden Durable Functions-Aufgabenhubs. Der Standardwert lautet DurableFunctionsHub. Der Wert kann auch über „durableTask:HubName“ in host.json festgelegt werden.

Wenn Sie keine Filter angeben (created-after, created-before oder runtime-status), ruft der Befehl einfach unabhängig von Laufzeitstatus oder Erstellungszeit top-Instanzen ab.

func durable get-instances --created-after 2021-03-10T13:57:31Z --created-before  2021-03-10T23:59Z --top 15

Beenden von Instanzen

Wenn die Ausführung einer Orchestrierungsinstanz zu lange dauert oder Sie sie aus beliebigem Grund vor dem Abschluss unterbrechen müssen, können Sie sie beenden.

Die beiden Parameter für die API zum Beenden sind eine instance ID und eine reason-Zeichenfolge, die in die Protokolle und in den Instanzstatus geschrieben werden.

[FunctionName("TerminateInstance")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("terminate-queue")] string instanceId)
{
    string reason = "Found a bug";
    return client.TerminateAsync(instanceId, reason);
}

Hinweis

Der vorherige C#-Code ist für Durable Functions 2.x vorgesehen. Für Durable Functions 1.x müssen Sie das OrchestrationClient-Attribut anstelle des DurableClient-Attributs verwenden, und Sie müssen den DurableOrchestrationClient-Parametertyp anstelle von IDurableOrchestrationClient verwenden. Weitere Informationen zu den Unterschieden zwischen den Versionen finden Sie im Artikel Durable Functions-Versionen.

Eine beendete Instanz wechselt schließlich in den Zustand Terminated. Dieser Übergang erfolgt jedoch nicht sofort. Stattdessen wird der Beendigungsvorgang im Aufgabenhub zusammen mit anderen Vorgängen für diese Instanz in eine Warteschlange eingereiht. Sie können die Instanzabfrage-APIs verwenden, um zu erfahren, wann eine beendete Instanz tatsächlich den Zustand Terminated erreicht hat.

Hinweis

Die Instanzbeendigung wird momentan nicht weitergegeben. Aktivitätsfunktionen und untergeordnete Orchestrierungen werden unabhängig davon, ob Sie die Orchestrierungsinstanz beendet haben, durch die sie aufgerufen wurden, bis zum Ende ausgeführt.

Anhalten und Fortsetzen von Instanzen

Durch das Anhalten einer Orchestrierung können Sie eine aktuell ausgeführte Orchestrierung beenden. Im Gegensatz zur Beendigung haben Sie die Möglichkeit, einen angehaltenen Orchestrator zu einem späteren Zeitpunkt fortzusetzen.

Die beiden Parameter für die API zum Anhalten sind eine Instanz-ID und eine Begründungszeichenfolge, die in die Protokolle und in den Instanzstatus geschrieben werden.

[FunctionName("SuspendResumeInstance")]
public static async Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("suspend-resume-queue")] string instanceId)
{
    string suspendReason = "Need to pause workflow";
    await client.SuspendAsync(instanceId, suspendReason);
    
    // Wait for 30 seconds to ensure that the orchestrator state is updated to suspended. 
    DateTime dueTime = context.CurrentUtcDateTime.AddSeconds(30);
    await context.CreateTimer(dueTime, CancellationToken.None);
    
    string resumeReason = "Continue workflow";
    await client.ResumeAsync(instanceId, resumeReason);
}

Eine angehaltene Instanz wechselt schließlich in den Zustand Suspended. Dieser Übergang erfolgt jedoch nicht sofort. Stattdessen wird der Anhaltevorgang im Aufgabenhub zusammen mit anderen Vorgängen für diese Instanz in eine Warteschlange eingereiht. Sie können die Instanzabfrage-APIs verwenden, um zu erfahren, wann eine aktuell ausgeführte Instanz den Zustand „Angehalten“ tatsächlich erreicht hat.

Wenn ein angehaltener Orchestrator fortgesetzt wird, ändert sich sein Status erneut in Running.

Azure Functions Core Tools

Sie können eine Orchestrierungsinstanz auch direkt mit dem func durable terminate-Befehl der Core Tools beenden.

Hinweis

Core Tools-Befehle werden derzeit nur unterstützt, wenn der Azure Storage-Standardanbieter zum Beibehalten des Runtimestatus verwendet wird.

Für den Befehl durable terminate werden die folgenden Parameter verwendet:

  • id (erforderlich) : Die ID der zu beendenden Orchestrierungsinstanz.
  • reason (optional) : Der Grund für die Beendigung.
  • connection-string-setting (optional) : Der Name der Anwendungseinstellung mit der zu verwendenden Speicherverbindungszeichenfolge. Der Standardwert lautet AzureWebJobsStorage.
  • task-hub-name (optional) : Der Name des zu verwendenden Durable Functions-Aufgabenhubs. Der Standardwert lautet DurableFunctionsHub. Der Wert kann auch über „durableTask:HubName“ in host.json festgelegt werden.

Der folgende Befehl beendet die Orchestrierungsinstanz mit der ID 0ab8c55a66644d68a3a8b220b12d209c:

func durable terminate --id 0ab8c55a66644d68a3a8b220b12d209c --reason "Found a bug"

Senden von Ereignissen an Instanzen

In einigen Szenarios müssen Orchestratorfunktionen auf externe Ereignisse warten und lauschen. Das ist beispielsweise bei Szenarios wie Überwachung oder menschlicher Interaktion nützlich.

Sie können Ereignisbenachrichtigungen an derzeit ausgeführte Instanzen senden, indem Sie die API zur Ereignisauslösung des Orchestrierungsclients verwenden. Orchestrationen können auf diese Ereignisse lauschen und darauf reagieren, indem sie die Orchestrator-API zum Warten auf ein externes Ereignis verwenden.

Die Parameter für die Ereignisauslösung lauten wie folgt:

  • Instanz-ID: Die eindeutige ID der Instanz.
  • Ereignisname: Der Name des zu sendenden Ereignisses.
  • Ereignisdaten: Mit JSON serialisierbare Nutzdaten, die an die Instanz gesendet werden.
[FunctionName("RaiseEvent")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("event-queue")] string instanceId)
{
    int[] eventData = new int[] { 1, 2, 3 };
    return client.RaiseEventAsync(instanceId, "MyEvent", eventData);
}

Hinweis

Der vorherige C#-Code ist für Durable Functions 2.x vorgesehen. Für Durable Functions 1.x müssen Sie das OrchestrationClient-Attribut anstelle des DurableClient-Attributs verwenden, und Sie müssen den DurableOrchestrationClient-Parametertyp anstelle von IDurableOrchestrationClient verwenden. Weitere Informationen zu den Unterschieden zwischen den Versionen finden Sie im Artikel Durable Functions-Versionen.

Hinweis

Ist keine Orchestrierungsinstanz mit der angegebenen Instanz-ID vorhanden, wird die Ereignisnachricht verworfen. Wenn eine Instanz vorhanden ist, aber noch nicht auf das Ereignis wartet, wird das Ereignis im Instanzstatus gespeichert, bis es für den Empfang und die Verarbeitung bereit ist.

Azure Functions Core Tools

Sie können ein Ereignis für eine Orchestrierungsinstanz auch direkt mit dem func durable raise-event-Befehl der Azure Core Tools auslösen.

Hinweis

Core Tools-Befehle werden derzeit nur unterstützt, wenn der Azure Storage-Standardanbieter zum Beibehalten des Runtimestatus verwendet wird.

Für den Befehl durable raise-event werden die folgenden Parameter verwendet:

  • id (erforderlich) : Die ID der Orchestrierungsinstanz.
  • event-name : Der Name des auszulösenden Ereignisses.
  • event-data (optional) : Die an die Orchestrierungsinstanz zu sendenden Daten. Dies kann der Pfad zu einer JSON-Datei sein, oder Sie können die Daten direkt in der Befehlszeile eingeben.
  • connection-string-setting (optional) : Der Name der Anwendungseinstellung mit der zu verwendenden Speicherverbindungszeichenfolge. Der Standardwert lautet AzureWebJobsStorage.
  • task-hub-name (optional) : Der Name des zu verwendenden Durable Functions-Aufgabenhubs. Der Standardwert lautet DurableFunctionsHub. Der Wert kann auch über „durableTask:HubName“ in host.json festgelegt werden.
func durable raise-event --id 0ab8c55a66644d68a3a8b220b12d209c --event-name MyEvent --event-data @eventdata.json
func durable raise-event --id 1234567 --event-name MyOtherEvent --event-data 3

Warten auf den Abschluss der Orchestrierung

Bei lange andauernden Orchestrierungen möchten Sie vielleicht warten und die Ergebnisse einer Orchestrierung erhalten. In diesen Fällen ist es auch sinnvoll, ein Timeout für die Orchestrierung definieren zu können. Wenn das Timeout überschritten wird, sollte der Status der Orchestrierung anstelle der Ergebnisse zurückgegeben werden.

Die API zum Warten auf den Abschluss oder die Erstellung einer Antwort zur Statusüberprüfung kann verwendet werden, um die tatsächliche Ausgabe einer Orchestrierungsinstanz synchron abzurufen. Standardmäßig umfasst diese Methode ein Timeout von 10 Sekunden und ein Abfrageintervall von 1 Sekunde.

Hier ist ein Beispiel für eine HTTP-Triggerfunktion angegeben, mit dem die Nutzung dieser API veranschaulicht wird:

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;

namespace VSSample
{
    public static class HttpSyncStart
    {
        private const string Timeout = "timeout";
        private const string RetryInterval = "retryInterval";

        [FunctionName("HttpSyncStart")]
        public static async Task<HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}/wait")]
            HttpRequestMessage req,
            [DurableClient] IDurableOrchestrationClient starter,
            string functionName,
            ILogger log)
        {
            // Function input comes from the request content.
            object eventData = await req.Content.ReadAsAsync<object>();
            string instanceId = await starter.StartNewAsync(functionName, eventData);

            log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

            TimeSpan timeout = GetTimeSpan(req, Timeout) ?? TimeSpan.FromSeconds(30);
            TimeSpan retryInterval = GetTimeSpan(req, RetryInterval) ?? TimeSpan.FromSeconds(1);
            
            return await starter.WaitForCompletionOrCreateCheckStatusResponseAsync(
                req,
                instanceId,
                timeout,
                retryInterval);
        }

        private static TimeSpan? GetTimeSpan(HttpRequestMessage request, string queryParameterName)
        {
            string queryParameterStringValue = request.RequestUri.ParseQueryString()[queryParameterName];
            if (string.IsNullOrEmpty(queryParameterStringValue))
            {
                return null;
            }

            return TimeSpan.FromSeconds(double.Parse(queryParameterStringValue));
        }
    }
}

Rufen Sie die Funktion mit der folgenden Zeile auf. Verwenden Sie 2 Sekunden für das Timeout und 0,5 Sekunden für das Wiederholungsintervall:

curl -X POST "http://localhost:7071/orchestrators/E1_HelloSequence/wait?timeout=2&retryInterval=0.5"

Hinweis

Der obige cURL-Befehl setzt voraus, dass Sie über eine Orchestratorfunktion namens E1_HelloSequence in Ihrem Projekt verfügen. Aufgrund der Art und Weise, wie die HTTP-Triggerfunktion geschrieben ist, können Sie sie durch den Namen einer beliebigen Orchestratorfunktion in Ihrem Projekt ersetzen.

Je nach Zeitraum, der zum Abrufen der Antwort aus der Orchestrierungsinstanz erforderlich ist, gibt es zwei Fälle:

  • Die Orchestrierungsinstanzen werden innerhalb des definierten Zeitraums (hier: 2 Sekunden) abgeschlossen, und die Antwort ist die tatsächliche Orchestrierungsinstanzausgabe, die synchron bereitgestellt wird:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Thu, 14 Dec 2021 06:14:29 GMT
Transfer-Encoding: chunked

[
    "Hello Tokyo!",
    "Hello Seattle!",
    "Hello London!"
]
  • Die Orchestrierungsinstanzen können nicht innerhalb des definierten Timeouts abgeschlossen werden, und die Antwort ist die Standardantwort, die unter Ermittlung der HTTP-API-URL beschrieben ist:
HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
Date: Thu, 14 Dec 2021 06:13:51 GMT
Location: http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177?taskHub={taskHub}&connection={connection}&code={systemKey}
Retry-After: 10
Transfer-Encoding: chunked

{
    "id": "d3b72dddefce4e758d92f4d411567177",
    "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/raiseEvent/{eventName}?taskHub={taskHub}&connection={connection}&code={systemKey}",
    "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177?taskHub={taskHub}&connection={connection}&code={systemKey}",
    "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/terminate?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}",
    "suspendPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/suspend?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}",
    "resumePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/resume?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}"
}

Hinweis

Das Format der Webhook-URLs kann in Abhängigkeit davon variieren, welche Version des Azure Functions-Hosts Sie ausführen. Das obige Beispiel gilt für den Azure Functions 3.0-Host.

Abrufen von HTTP-Management-Webhook-URLs

Sie können ein externes System zum Überwachen oder zum Auslösen von Ereignissen bei einer Orchestrierung verwenden. Externe Systeme können mit Durable Functions über die Webhook-URLs kommunizieren, die Teil der in HTTP-APIs in Durable Functions (Azure Functions) beschriebenen Standardantwort sind. Der Zugriff auf die Webhook-URLs kann auch programmgesteuert mithilfe der Orchestrierungsclientbindung erfolgen. Insbesondere kann die API zum Erstellen von HTTP-Verwaltungsnutzdaten verwendet werden, um ein serialisierbares Objekt zu erhalten, das diese Webhook-URLs enthält.

Die API zum Erstellen von HTTP-Verwaltungsnutzdaten umfasst einen Parameter:

  • Instanz-ID: Die eindeutige ID der Instanz.

Die Methoden geben ein Objekt mit den folgenden Zeichenfolgeneigenschaften zurück:

  • Id: Die Instanz-ID der Orchestrierung (muss mit der Eingabe InstanceId identisch sein).
  • StatusQueryGetUri: Status-URL der Orchestrierungsinstanz
  • SendEventPostUri: URL der Orchestrierungsinstanz für die „Ereignisauslösung“
  • TerminatePostUri: URL der Orchestrierungsinstanz für die „Beendigung“
  • PurgeHistoryDeleteUri: URL der Orchestrierungsinstanz für den „Bereinigungsverlauf“
  • suspendPostUri: Die „Anhalten“-URL der Orchestrierungsinstanz.
  • resumePostUri: Die „Fortsetzen“-URL der Orchestrierungsinstanz.

Funktionen können Instanzen dieser Objekte an externe Systeme senden, um Ereignisse in den entsprechenden Orchestrierungen zu überwachen oder auszulösen, wie in den folgenden Beispielen gezeigt:

[FunctionName("SendInstanceInfo")]
public static void SendInstanceInfo(
    [ActivityTrigger] IDurableActivityContext ctx,
    [DurableClient] IDurableOrchestrationClient client,
    [CosmosDB(
        databaseName: "MonitorDB",
        containerName: "HttpManagementPayloads",
        Connection = "CosmosDBConnectionSetting")]out dynamic document)
{
    HttpManagementPayload payload = client.CreateHttpManagementPayload(ctx.InstanceId);

    // send the payload to Azure Cosmos DB
    document = new { Payload = payload, id = ctx.InstanceId };
}

Hinweis

Der vorherige C#-Code ist für Durable Functions 2.x vorgesehen. Für Durable Functions 1.x müssen Sie DurableActivityContext anstelle von IDurableActivityContext verwenden, Sie müssen das OrchestrationClient-Attribut anstelle des DurableClient-Attributs verwenden, und Sie müssen den DurableOrchestrationClient-Parametertyp anstelle von IDurableOrchestrationClient verwenden. Weitere Informationen zu den Unterschieden zwischen den Versionen finden Sie im Artikel Durable Functions-Versionen.

Zurückspulen von Instanzen (Vorschau)

Wenn bei einer Orchestrierung aus unerwartetem Grund Fehler auftreten, können Sie die Instanz mithilfe einer für diesen Zweck erstellten API auf einen fehlerfreien früheren Zustand zurückspulen.

Hinweis

Diese API ist nicht als Ersatz für ordnungsgemäße Richtlinien zur Fehlerbehandlung und Wiederholung gedacht. Sie soll nur in Fällen verwendet werden, in denen Orchestrierungsinstanzen aus unerwarteten Gründen ausfallen. Orchestrierungen in anderen Zuständen als Failed (z. B. Running, Pending, Terminated, Completed) können nicht „zurückgespult“ werden. Weitere Informationen zur Fehlerbehandlung und zu Wiederholungsrichtlinien finden Sie im Artikel Fehlerbehandlung.

Verwenden Sie die Methode RewindAsync (.NET) oder rewind (JavaScript) der Orchestrierungsclientbindung, um die Orchestrierung erneut in den Zustand Ausgeführt zu versetzen. Diese Methode führt auch die Aktivität oder die Ausführungsfehler der untergeordneten Orchestrierung, die den Orchestrierungsfehler verursacht hat, erneut aus.

Stellen Sie sich als Beispiel einen Workflow vor, der eine Reihe von menschlichen Genehmigungen umfasst. Angenommen, eine Reihe von Aktivitätsfunktionen benachrichtigt jemanden, dass seine Genehmigung erforderlich ist, und wartet in Echtzeit auf die Antwort. Stellen Sie sich vor, dass nachdem alle Genehmigungsaktivitäten Antworten erhalten haben oder abgelaufen sind, aufgrund einer Fehlkonfiguration einer Anwendung, z.B. einer ungültige Datenbank-Verbindungszeichenfolge, ein Fehler bei einer anderen Aktivität auftritt. Das Ergebnis ist ein Orchestrierungsfehler tief im Workflow. Mit der RewindAsync-API (.NET) oder rewind-API (JavaScript) kann ein Anwendungsadministrator den Konfigurationsfehler beheben und die fehlerhafte Orchestrierung zum Zustand unmittelbar vor dem Fehler zurückspulen. Keiner der Schritte, die menschliche Interaktion erforderten, muss erneut genehmigt werden, und die Orchestrierung kann jetzt erfolgreich abgeschlossen werden.

Hinweis

Die Funktion Zurückspulen unterstützt kein Zurückspulen von Orchestrierungsinstanzen, die permanente Timer verwenden.

[FunctionName("RewindInstance")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("rewind-queue")] string instanceId)
{
    string reason = "Orchestrator failed and needs to be revived.";
    return client.RewindAsync(instanceId, reason);
}

Hinweis

Der vorherige C#-Code ist für Durable Functions 2.x vorgesehen. Für Durable Functions 1.x müssen Sie das OrchestrationClient-Attribut anstelle des DurableClient-Attributs verwenden, und Sie müssen den DurableOrchestrationClient-Parametertyp anstelle von IDurableOrchestrationClient verwenden. Weitere Informationen zu den Unterschieden zwischen den Versionen finden Sie im Artikel Durable Functions-Versionen.

Azure Functions Core Tools

Sie können eine Orchestrierungsinstanz auch direkt mit dem func durable rewind-Befehl der Core Tools zurückspulen.

Hinweis

Core Tools-Befehle werden derzeit nur unterstützt, wenn der Azure Storage-Standardanbieter zum Beibehalten des Runtimestatus verwendet wird.

Für den Befehl durable rewind werden die folgenden Parameter verwendet:

  • id (erforderlich) : Die ID der Orchestrierungsinstanz.
  • reason (optional) : Der Grund für das Zurückspulen der Orchestrierungsinstanz.
  • connection-string-setting (optional) : Der Name der Anwendungseinstellung mit der zu verwendenden Speicherverbindungszeichenfolge. Der Standardwert lautet AzureWebJobsStorage.
  • task-hub-name (optional) : Der Name des zu verwendenden Durable Functions-Aufgabenhubs. Standardmäßig wird der Aufgabenhubname in der Datei host.json verwendet.
func durable rewind --id 0ab8c55a66644d68a3a8b220b12d209c --reason "Orchestrator failed and needs to be revived."

Löschen des Instanzverlaufs

Um alle Daten im Zusammenhang mit einer Orchestrierung zu entfernen, können Sie den Instanzverlauf löschen. Ein Beispiel: Sie möchten alle Speicherressourcen löschen, die einer beendeten Instanz zugeordnet sind. Verwenden Sie dazu die vom Orchestrierungsclient definierte API zur Instanzlöschung.

Dieses erste Beispiel zeigt, wie Sie eine einzelne Orchestrierungsinstanz löschen können.

[FunctionName("PurgeInstanceHistory")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("purge-queue")] string instanceId)
{
    return client.PurgeInstanceHistoryAsync(instanceId);
}

Das nächste Beispiel zeigt eine von einem Timer ausgelöste Funktion, die den Verlauf für alle Orchestrierungsinstanzen löscht, die nach Ablauf der angegebenen Zeitspanne abgeschlossen wurden. In diesem Fall werden die Daten für alle Instanzen entfernt, die vor mindestens 30 Tagen abgeschlossen wurden. Diese Beispielfunktion wird einmal täglich um 12:00 Uhr UTC ausgeführt:

[FunctionName("PurgeInstanceHistory")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [TimerTrigger("0 0 12 * * *")] TimerInfo myTimer)
{
    return client.PurgeInstanceHistoryAsync(
        DateTime.MinValue,
        DateTime.UtcNow.AddDays(-30),  
        new List<OrchestrationStatus>
        {
            OrchestrationStatus.Completed
        });
}

Hinweis

Der vorherige C#-Code ist für Durable Functions 2.x vorgesehen. Für Durable Functions 1.x müssen Sie das OrchestrationClient-Attribut anstelle des DurableClient-Attributs verwenden, und Sie müssen den DurableOrchestrationClient-Parametertyp anstelle von IDurableOrchestrationClient verwenden. Weitere Informationen zu den Unterschieden zwischen den Versionen finden Sie im Artikel Durable Functions-Versionen.

Hinweis

Damit der Vorgang zum Bereinigen des Verlaufs erfolgreich ist, muss der Laufzeitstatus der Zielinstanz Abgeschlossen, Beendetoder Fehlgeschlagenen sein.

Azure Functions Core Tools

Sie können den Verlauf einer Orchestrierungsinstanz mit dem func durable purge-history-Befehl der Core Tools bereinigen. Ähnlich wie im zweiten C#-Beispiel im vorherigen Abschnitt wird der Verlauf für alle Orchestrierungsinstanzen gelöscht, die während eines angegebenen Zeitintervalls erstellt wurden. Sie können gelöschte Instanzen weiter nach dem Laufzeitstatus filtern.

Hinweis

Core Tools-Befehle werden derzeit nur unterstützt, wenn der Azure Storage-Standardanbieter zum Beibehalten des Runtimestatus verwendet wird.

Der Befehl durable purge-history verfügt über mehrere Parameter:

  • created-after (optional) : Löscht den Verlauf der nach diesem Datum/dieser Uhrzeit (UTC) erstellten Instanzen. Es werden nach ISO 8601 formatierte datetime-Werte akzeptiert.
  • created-before (optional) : Löscht den Verlauf der vor diesem Datum/dieser Uhrzeit (UTC) erstellten Instanzen. Es werden nach ISO 8601 formatierte datetime-Werte akzeptiert.
  • runtime-status (optional) : Löschen Sie den Verlauf von Instanzen mit einem bestimmten Status (z.B. „Ausgeführt“ oder „Abgeschlossen“). Es können mehrere Status angegeben werden (Leerzeichen als Trennzeichen).
  • connection-string-setting (optional) : Der Name der Anwendungseinstellung mit der zu verwendenden Speicherverbindungszeichenfolge. Der Standardwert lautet AzureWebJobsStorage.
  • task-hub-name (optional) : Der Name des zu verwendenden Durable Functions-Aufgabenhubs. Standardmäßig wird der Aufgabenhubname in der Datei host.json verwendet.

Der folgende Befehl löscht den Verlauf aller fehlerhaften Instanzen, die vor dem 14. November 2021 um 19:35 Uhr UTC erstellt wurden.

func durable purge-history --created-before 2021-11-14T19:35:00.0000000Z --runtime-status failed

Löschen eines Aufgabenhubs

Mithilfe des func durable delete-task-hub-Befehls in den Core Tools können Sie alle Speicherartefakte löschen, die einem bestimmten Aufgabenhub zugeordnet sind, einschließlich Azure Storage-Tabellen, -Abfragen und -Blobs.

Hinweis

Core Tools-Befehle werden derzeit nur unterstützt, wenn der Azure Storage-Standardanbieter zum Beibehalten des Runtimestatus verwendet wird.

Der Befehl durable delete-task-hub verfügt über zwei Parameter:

  • connection-string-setting (optional) : Der Name der Anwendungseinstellung mit der zu verwendenden Speicherverbindungszeichenfolge. Der Standardwert lautet AzureWebJobsStorage.
  • task-hub-name (optional) : Der Name des zu verwendenden Durable Functions-Aufgabenhubs. Standardmäßig wird der Aufgabenhubname in der Datei host.json verwendet.

Der folgende Befehl löscht alle Azure Storage-Daten, die dem Aufgabenhub UserTest zugeordnet sind.

func durable delete-task-hub --task-hub-name UserTest

Nächste Schritte

Versioning in Durable Functions (Azure Functions) (Versionsverwaltung in Durable Functions [Azure Functions])