Hantera orkestreringsinstanser

Använd de inbyggda instanshanterings-API:erna för att starta, fråga, avsluta, pausa, återuppta och rensa orkestreringsinstanser i dina varaktiga arbetsflöden. I Durable Functions exponerar klientbindningen orchestration dessa API:er. I SDK:erna för varaktiga uppgifter är samma åtgärder tillgängliga via DurableTaskClient klassen. Den här artikeln visar hur du utför varje instanshanteringsåtgärd med kodexempel för båda plattformarna.

Tips/Råd

Azure Durable Task Scheduler är den rekommenderade serverdelen för både Durable Functions och Durable Task SDK:er, vilket ger en fullständigt hanterad, serverlös upplevelse för att köra hållbara arbetsflöden i stor skala.

Starta instanser

Metoden start-new (eller schedule-new) på orkestreringsklienten startar en ny orkestreringsinstans. Internt skriver denna metod ett meddelande till den konfigurerade backend (såsom Durable Task Scheduler) och returnerar sedan. Det här meddelandet utlöser asynkront början på en orkestrering med det angivna namnet.

Här är parametrarna för att starta en ny orkestreringsinstans:

Parameter Description
Namn Namnet på orkestratörfunktionen för schemaläggning.
Input All JSON-serialiserbar data som ska skickas som indata till orkestratorfunktionen.
InstanceId (Valfritt) Den unika identifieringen av instansen. Om du inte anger den här parametern använder metoden ett slumpmässigt ID.

Tips/Råd

Använd en slumpmässig identifierare för instans-ID:t när det är möjligt. Slumpmässiga instans-ID:er hjälper till att säkerställa en lika belastningsfördelning när du skalar orkestreringsfunktioner över flera virtuella datorer. Det är rätt tid att använda icke-slumpmässiga instans-ID när ID:t kommer från en extern källa eller när du implementerar singleton orchestrator-mönstret.

Parameter Description
Namn Namnet på den orkestrering som ska schemaläggas.
Input All JSON-serialiserbar data som ska skickas som indata till orkestreringen.
InstanceId (Valfritt) Den unika identifieringen av instansen. Om du inte anger den här parametern använder metoden ett slumpmässigt ID.

Tips/Råd

Använd en slumpmässig identifierare för instans-ID:t när det är möjligt. Slumpmässiga instans-ID:er hjälper till att säkerställa en lika belastningsfördelning när du skalar orkestreringar över flera virtuella datorer. Det är rätt tid att använda icke-slumpmässiga instans-ID när ID:t kommer från en extern källa eller när du implementerar singleton orchestrator-mönstret.

Följande exempelfunktion startar en ny orkestreringsinstans:

Isolerad arbetsmodell
[Function("HelloWorldQueueTrigger")]
public static async Task Run(
    [QueueTrigger("start-queue")] string input,
    [DurableClient] DurableTaskClient client,
    FunctionContext functionContext)
{
    string instanceId = await client.ScheduleNewOrchestrationInstanceAsync("HelloWorld", input);
    functionContext.GetLogger("HelloWorldQueueTrigger")
        .LogInformation("Started orchestration with ID = '{InstanceId}'.", instanceId);
}

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

Viktigt!

PowerShell Durable Task SDK är för närvarande inte tillgängligt.

Följande kod visar hur du startar en ny orkestreringsinstans med hjälp av Durable Task SDK:er:

using Microsoft.DurableTask.Client;

// Schedule a new orchestration instance
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync("HelloWorld", input);
Console.WriteLine($"Started orchestration with ID = '{instanceId}'.");

// Optionally, wait for the orchestration to start
OrchestrationMetadata metadata = await client.WaitForInstanceStartAsync(instanceId, timeout: TimeSpan.FromSeconds(30));

Frågeinstanser

När du har startat nya orkestreringsinstanser behöver du troligen göra förfrågningar om deras körstatus för att få reda på om de körs, är slutförda eller har misslyckats.

Metoden get-status på orkestreringsklienten returnerar statusen för en orkestreringsinstans.

Det tar en instanceId (obligatorisk), showHistory (valfritt), showHistoryOutput (valfritt) och showInput (valfritt) som parametrar.

  • showHistory: Om det är inställt på true, innehåller svaret körningshistoriken.
  • showHistoryOutput: Om det är inställt på true, innehåller körningshistoriken aktivitetsutdata.
  • showInput: Om det är inställt falsepå innehåller svaret inte indata för funktionen. Standardvärdet är true.

Metoden returnerar ett objekt med följande egenskaper:

Property Description
Namn Namnet på orkestratörfunktionen.
InstanceId Instans-ID:t för orkestreringen (bör vara detsamma som instanceId inmatningen).
CreatedTime Den tidpunkt då orkestratorfunktionen börjar köras.
LastUpdatedTime Tidpunkten då orkestreringen senast skapade en kontrollpunkt.
Input Funktionens indata som ett JSON-värde. Det här fältet fylls inte i om showInput är false.
CustomStatus Anpassad orkestreringsstatus i JSON-format.
Output Utdata från funktionen som ett JSON-värde (om funktionen fullbordas). Om orkestreringsfunktionen misslyckas innehåller den här egenskapen information om felet. Om orkestreringsfunktionen pausas eller avslutas innehåller den här egenskapen orsaken till avstängningen eller avslutningen (om någon).
RuntimeStatus: Väntar Instansen är schemalagd men har ännu inte börjat köras.
RuntimeStatus: Körs Instansen körs.
RuntimeStatus: Slutförd Instansen avslutades normalt.
KörtidStatus: FortsätterSom Nytt Instansen startade om med en ny historik. Det här tillståndet är ett tillfälligt tillstånd.
RuntimeStatus: Misslyckades Instansen misslyckades på grund av ett fel.
RuntimeStatus: Avslutad Händelsen avbröts abrupt.
RuntimeStatus: Pausad Instansen avbryts och kan återupptas senare.
History Genomförandehistoriken för orkestreringen. Det här fältet fylls bara i om showHistory är inställt på true.
Parameter Description
showHistory Om den sätts till true, innehåller svaret exekveringshistoriken.
showHistoryOutput Om den sätts till true, innehåller exekveringshistoriken aktivitetsutdata.
showInput Om värdet är false, innehåller svaret inte indata till orkestreringen. Standardvärdet är true.

Metoden returnerar ett objekt med följande egenskaper:

Property Description
Namn Namnet på orkestreringen.
InstanceId Instans-ID:t för orkestreringen (bör vara detsamma som instanceId inmatningen).
CreatedTime Tidpunkten då orkestreringen börjar köras.
LastUpdatedTime Tidpunkten då orkestreringen senast skapade en kontrollpunkt.
Input Indata för orkestreringen som ett JSON-värde. Det här fältet fylls inte i om showInput är false.
CustomStatus Anpassad orkestreringsstatus i JSON-format.
Output Utdata från orkestreringen som ett JSON-värde (om orkestreringen slutförs). Om orkestreringen misslyckas innehåller den här egenskapen information om felet. Om orkestreringen avbryts eller avslutas innehåller den här egenskapen orsaken till avstängningen eller uppsägningen (om någon).
RuntimeStatus: Väntar Instansen är schemalagd men har ännu inte börjat köras.
RuntimeStatus: Körs Instansen körs.
RuntimeStatus: Slutförd Instansen slutfördes normalt.
KörtidStatus: FortsätterSom Nytt Instansen startade om sig själv med en ny historia. Det här tillståndet är ett tillfälligt tillstånd.
RuntimeStatus: Misslyckades Instansen misslyckades på grund av ett fel.
RuntimeStatus: Avslutad Händelsen avbröts abrupt.
RuntimeStatus: Pausad Instansen avbryts och kan återupptas vid ett senare tillfälle.
History Genomförandehistoriken för orkestreringen. Det här fältet fylls bara i om showHistory är inställt på true.

Anmärkning

En orkestrerare markeras inte som Completed förrän alla schemalagda uppgifter har slutförts och orkestratorn återvänder. Med andra ord räcker det inte att en orkestrerare når sin return instruktion för att den ska markeras som Completed. Detta är särskilt relevant för fall där WhenAny används; dessa orkestratorer ofta return innan alla schemalagda uppgifter körs.

Den här metoden returnerar null (.NET och Java), undefined (JavaScript) eller None (Python) om instansen inte finns.

Isolerad arbetsmodell
[Function("GetStatus")]
public static async Task Run(
    [DurableClient] DurableTaskClient client,
    [QueueTrigger("check-status-queue")] string instanceId)
{
    OrchestrationMetadata? metadata = await client.GetInstanceAsync(
        instanceId,
        getInputsAndOutputs: true);
    // Do something based on the current status.
}

Processmodell
[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.
}

using Microsoft.DurableTask.Client;

// Get the status of an orchestration instance
OrchestrationMetadata? metadata = await client.GetInstanceAsync(instanceId, getInputsAndOutputs: true);
if (metadata != null)
{
    OrchestrationRuntimeStatus status = metadata.RuntimeStatus;
    // do something based on the current status
}

Hämta alla orkestreringsinstanser

Du kan använda API:er i ditt språk-SDK för att fråga efter status för alla orkestreringsinstanser i aktivitetshubben. Det här "list-instances" eller "get-status"- API:et returnerar en lista över objekt som representerar orkestreringsinstanserna som matchar frågeparametrarna.

Isolerad arbetsmodell
[Function("GetAllStatus")]
public static async Task Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData request,
    [DurableClient] DurableTaskClient client,
    FunctionContext functionContext)
{
    ILogger logger = functionContext.GetLogger("GetAllStatus");
    AsyncPageable<OrchestrationMetadata> instances = client.GetAllInstancesAsync(
        new OrchestrationQuery());

    await foreach (OrchestrationMetadata instance in instances)
    {
        logger.LogInformation("{Instance}", instance);
    }
}

Processmodell
[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.
}

using Microsoft.DurableTask.Client;

// Query all orchestration instances
AsyncPageable<OrchestrationMetadata> instances = client.GetAllInstancesAsync(new OrchestrationQuery());

await foreach (OrchestrationMetadata instance in instances)
{
    Console.WriteLine(instance.InstanceId);
}

Sök orkestreringsinstanser med filter

Vad händer om du inte behöver all information som en standardinstansfråga tillhandahåller? Vad händer om du till exempel bara letar efter orkestreringsgenereringstiden eller orkestreringskörningsstatusen? Begränsa frågan genom att använda filter.

Isolerad arbetsmodell
[Function("QueryStatus")]
public static async Task Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData request,
    [DurableClient] DurableTaskClient client,
    FunctionContext functionContext)
{
    ILogger logger = functionContext.GetLogger("QueryStatus");
    var query = new OrchestrationQuery
    {
        Statuses = new[]
        {
            OrchestrationRuntimeStatus.Pending,
            OrchestrationRuntimeStatus.Running,
        },
        CreatedFrom = DateTime.UtcNow.Subtract(TimeSpan.FromDays(7)),
        CreatedTo = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)),
        PageSize = 100,
    };

    await foreach (OrchestrationMetadata instance in client.GetAllInstancesAsync(query))
    {
        logger.LogInformation("{Instance}", instance);
    }
}

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

using Microsoft.DurableTask.Client;

// Get running or pending instances created in the last 7 days
var query = new OrchestrationQuery
{
    Statuses = new[] { OrchestrationRuntimeStatus.Running, OrchestrationRuntimeStatus.Pending },
    CreatedFrom = DateTime.UtcNow.AddDays(-7),
    CreatedTo = DateTime.UtcNow.AddDays(-1),
    PageSize = 100
};

AsyncPageable<OrchestrationMetadata> instances = client.GetAllInstancesAsync(query);

await foreach (OrchestrationMetadata instance in instances)
{
    Console.WriteLine($"{instance.InstanceId}: {instance.RuntimeStatus}");
}

Avsluta orkestreringsinstanser

Om du har en orkestreringsinstans som tar för lång tid att köra, eller om du behöver stoppa den innan den slutförs av någon anledning, kan du avsluta den.

De två parametrarna för termins-API:et är ett instans-ID och en orsakssträng som skriver till loggar och till instansstatusen.

Isolerad arbetsmodell
[Function("TerminateInstance")]
public static Task Run(
    [DurableClient] DurableTaskClient client,
    [QueueTrigger("terminate-queue")] string instanceId)
{
    string reason = "Found a bug";
    return client.TerminateInstanceAsync(instanceId, reason);
}

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

using Microsoft.DurableTask.Client;

string reason = "Found a bug";
await client.TerminateInstanceAsync(instanceId, reason);

En avslutad instans övergår så småningom till tillståndet Terminated . Men den här övergången sker inte omedelbart. I stället placeras avslutningsåtgärden i aktivitetshubben tillsammans med andra åtgärder för denna instans. Du kan använda API:erna för instansfrågor för att veta när en avslutad instans faktiskt har nått Terminated tillståndet.

Anmärkning

Instansnedstängning sprids just nu inte. Aktivitetsfunktioner och underorkestreringar körs tills de är klara, oavsett om du avslutar den orkestreringsinstans som anropade dem.

Pausa och återuppta orkestreringsinstanser

Om du pausar en orkestrering kan du stoppa en orkestrering som körs. Till skillnad från att avsluta en orkestrering kan du återuppta en pausad orkestrerare senare.

De två parametrarna för det pausade API:et är ett instans-ID och en orsakssträng som skrivs till loggar och till instansstatusen.

Isolerad arbetsmodell
[Function("SuspendResumeInstance")]
public static async Task Run(
    [DurableClient] DurableTaskClient client,
    [QueueTrigger("suspend-resume-queue")] string instanceId)
{
    // To suspend an orchestration
    string suspendReason = "Need to pause workflow";
    await client.SuspendInstanceAsync(instanceId, suspendReason);

    // To resume an orchestration
    string resumeReason = "Continue workflow";
    await client.ResumeInstanceAsync(instanceId, resumeReason);
}

Processmodell
[FunctionName("SuspendResumeInstance")]
public static async Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("suspend-resume-queue")] string instanceId)
{
    // To suspend an orchestration
    string suspendReason = "Need to pause workflow";
    await client.SuspendAsync(instanceId, suspendReason);

    // To resume an orchestration
    string resumeReason = "Continue workflow";
    await client.ResumeAsync(instanceId, resumeReason);
}

using Microsoft.DurableTask.Client;

// To suspend an orchestration
string suspendReason = "Need to pause workflow";
await client.SuspendInstanceAsync(instanceId, suspendReason);

// To resume an orchestration
string resumeReason = "Continue workflow";
await client.ResumeInstanceAsync(instanceId, resumeReason);

En pausad instans övergår så småningom till tillståndet Suspended . Den här övergången sker dock inte omedelbart. Pausåtgärden placeras i stället i aktivitetshubben tillsammans med andra åtgärder för den instansen. Använd API:erna för instansfrågor för att veta när en instans som körs faktiskt har nått tillståndet Suspended .

När en pausad orkestrerare återupptas ändras dess status tillbaka till Running.

Skicka händelser till instanser

I vissa scenarier måste orkestreringsfunktioner vänta och lyssna efter externa händelser. Exempel där den här metoden är användbar är scenarier för övervakning och mänsklig interaktion .

I vissa scenarier måste orkestreringar vänta och lyssna efter externa händelser. Exempel där den här metoden är användbar är scenarier för övervakning och mänsklig interaktion .

Du kan skicka händelsemeddelanden till instanser som körs med hjälp av api:et för att skapa händelse i orkestreringsklienten. Orkestreringar kan lyssna på och svara på dessa händelser genom att använda orkestrerar-API:t för att vänta på externa händelser.

Parametrarna för höjningshändelsen är:

  • Instans-ID: Instansens unika ID.
  • Händelsenamn: Namnet på den händelse som ska skickas.
  • Händelsedata: En JSON-serialiserbar nyttolast som ska skickas till instansen.
Isolerad arbetsmodell
[Function("RaiseEvent")]
public static Task Run(
    [DurableClient] DurableTaskClient client,
    [QueueTrigger("event-queue")] string instanceId)
{
    int[] eventData = new int[] { 1, 2, 3 };
    return client.RaiseEventAsync(instanceId, "MyEvent", eventData);
}

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

using Microsoft.DurableTask.Client;

int[] eventData = new int[] { 1, 2, 3 };
await client.RaiseEventAsync(instanceId, "MyEvent", eventData);

Anmärkning

Om det inte finns någon orkestreringsinstans med det angivna instans-ID:t ignoreras händelsemeddelandet. Om det finns en instans men den ännu inte väntar på händelsen lagras händelsen i instanstillståndet tills den är redo att tas emot och bearbetas.

Vänta tills orkestrering har slutförts

I långvariga orkestreringar kanske du vill vänta och få resultatet av en orkestrering. I dessa fall är det också användbart att definiera en tidsgräns för orkestreringen. Om tidsgränsen överskrids returneras orkestreringens tillstånd i stället för resultatet.

Använd API :et "vänta på slutförande eller skapa svar på kontrollstatus" för att hämta faktiska utdata från en orkestreringsinstans synkront. Som standard har den här metoden en timeout på tio sekunder och ett avsökningsintervall på en sekund.

Här är ett exempel på en HTTP-utlösarfunktion som visar hur du använder det här API:et:

Isolerad arbetsmodell
[Function("HttpSyncStart")]
public static async Task<HttpResponseData> Run(
    [HttpTrigger(
        AuthorizationLevel.Function,
        "post",
        Route = "orchestrators/{functionName}/wait")] HttpRequestData request,
    [DurableClient] DurableTaskClient client,
    string functionName)
{
    string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(functionName);

    using var timeoutCancellation = new CancellationTokenSource(TimeSpan.FromSeconds(30));
    return await client.WaitForCompletionOrCreateCheckStatusResponseAsync(
        request,
        instanceId,
        timeoutCancellation.Token);
}

Processmodell
// 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));
        }
    }
}

SDK:er för varaktiga uppgifter tillhandahåller en metod för att vänta tills en orkestrering slutförs synkront.

using Microsoft.DurableTask.Client;

// Wait for orchestration to complete with a timeout
OrchestrationMetadata metadata = await client.WaitForInstanceCompletionAsync(
    instanceId,
    timeout: TimeSpan.FromSeconds(30),
    getInputsAndOutputs: true);

if (metadata.RuntimeStatus == OrchestrationRuntimeStatus.Completed)
{
    Console.WriteLine($"Output: {metadata.SerializedOutput}");
}

Anropa funktionen med följande rad. Använd två sekunder för tidsgränsen och 0,5 sekunder för återförsöksintervallet:

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

Anmärkning

Ovanstående cURL-kommando förutsätter att du har en orchestrator-funktion med namnet E1_HelloSequence i projektet. På grund av hur HTTP-utlösarfunktionen skrivs kan du ersätta den med namnet på valfri orkestreringsfunktion i projektet.

Beroende på den tid som krävs för att hämta svaret från orkestreringsinstansen finns det två fall:

  • Orkestreringsinstanserna avslutas inom den definierade tidsgränsen (i det här fallet två sekunder), och svaret är den faktiska orkestreringsinstansens utdata, som levereras synkront:
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!"
]
  • Orkestreringsinstanserna kan inte slutföras inom den definierade tidsgränsen, och svaret är standarden som beskrivs i HTTP API URL-upptäckt:
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}"
}

Anmärkning

Formatet på webhooks-URL:erna kan variera beroende på vilken version av Azure Functions värd du kör. Föregående exempel är för Azure Functions 3.0-värdmiljö.

Hämta HTTP-hanteringswebbhooks-URL:er för orkestreringsinstanser

Använd ett externt system för att övervaka eller utlösa händelser för en orkestrering. Externa system kommunicerar med Durable Functions via webhook-URL:er som ingår i standardsvaret som beskrivs i HTTP API URL-identifiering. Webhook-URL:erna är alternativt tillgängliga programmatiskt med hjälp av orkestreringsklientbindningen. Mer specifikt hämtar API:et create HTTP management payload ett serialiserbart objekt som innehåller dessa webhook-URL:er.

API för att skapa HTTP-hanteringsnyttolast har en parameter:

  • Instans-ID: Instansens unika ID.

Metoderna returnerar ett objekt med följande strängegenskaper:

  • ID: Instans-ID för orkestreringen (bör vara samma som InstanceId indata).
  • StatusQueryGetUri: Status-URL:en för orkestreringsinstansen.
  • SendEventPostUri: URL för att "utlösa händelse" med orkestreringsinstansen.
  • TerminatePostUri: "avsluta"-URL:en för orkestreringsinstansen.
  • PurgeHistoryDeleteUri: URL:en för "rensningshistorik" för orkestreringsinstansen.
  • SuspendPostUri: URL för att suspendera orkestreringsinstansen.
  • ResumePostUri: Den "återuppta" URL:en för orkestreringsinstansen.

Funktioner skickar instanser av dessa objekt till externa system för att övervaka eller utlösa händelser på motsvarande orkestreringar, som visas i följande exempel.

Isolerad arbetsmodell
[Function("SendInstanceInfo")]
[CosmosDBOutput(
    databaseName: "MonitorDB",
    containerName: "HttpManagementPayloads",
    Connection = "CosmosDBConnectionSetting")]
public static object SendInstanceInfo(
    [ActivityTrigger] TaskActivityContext context,
    [DurableClient] DurableTaskClient client)
{
    HttpManagementPayload payload = client.CreateHttpManagementPayload(context.InstanceId);

    // Send the payload to Azure Cosmos DB.
    return new { Payload = payload, id = context.InstanceId };
}

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

Spola tillbaka orkestreringsinstanser

Om du har ett orkestreringsfel av en oväntad anledning spolar du tillbaka instansen till ett tidigare felfritt tillstånd med hjälp av ett API som skapats för det ändamålet.

Anmärkning

Det här API:et är inte avsett att ersätta korrekt felhantering och återförsöksprinciper. Det är i stället avsett att endast användas i fall där orkestreringsinstanser misslyckas av oväntade skäl. Orkestreringar i andra tillstånd än Failed (till exempel Running, Pending, Terminatedeller Completed) kan inte "återskapas". Mer information om felhantering och återförsöksprinciper finns i artikeln Felhantering .

Använd metoden RewindAsync (.NET) eller rewind (JavaScript) för klientbindningen orchestration för att återställa orkestreringen till Running. Den här metoden kör också om körningsfelen för aktiviteten eller delorchestrationen som orsakade orkestreringsfelet.

Anta till exempel att du har ett arbetsflöde som omfattar en rad mänskliga godkännanden. Anta att en serie aktivitetsfunktioner meddelar någon att deras godkännande behövs och väntar ut realtidssvaret. När alla godkännandeaktiviteter har fått svar eller blivit tidsbegränsade, kan vi anta att en annan aktivitet misslyckas på grund av ett konfigurationsfel i applikationen, som till exempel en ogiltig databasanslutningssträng. Resultatet är ett orkestreringsfel djupt in i arbetsflödet. Med API:et RewindAsync (.NET) eller rewind (JavaScript) kan en programadministratör åtgärda konfigurationsfelet och spola tillbaka den misslyckade orkestreringen till tillståndet omedelbart före felet. Inget av stegen för mänsklig interaktion behöver godkännas på nytt och orkestreringen kan nu slutföras.

Anmärkning

Återspolningsfunktionen har inte stöd för att spola tillbaka orkestreringsinstanser som använder varaktiga timers.

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

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

using Microsoft.DurableTask.Client;

string reason = "Orchestrator failed and needs to be revived.";
await client.RewindInstanceAsync(instanceId, reason);

Starta om orkestreringsinstanser

Om du startar om en orkestrering skapas en ny instans med hjälp av historiken från en tidigare körd instans. Den här funktionen är användbar när du vill köra en orkestrering igen med samma indata- och instans-ID-mönster, vilket skapar en ny körning baserat på originalet.

Isolerad arbetsmodell
[Function("RestartInstance")]
public static Task<string?> Run(
    [DurableClient] DurableTaskClient client,
    [QueueTrigger("restart-queue")] string instanceId)
{
    return client.RestartAsync(instanceId, restartWithNewInstanceId: true);
}

Processmodell
[FunctionName("RestartInstance")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("restart-queue")] string instanceId)
{
    return client.RestartAsync(instanceId, restartWithNewInstanceId: true);
}

using Microsoft.DurableTask.Client;

// Restart an orchestration with a new instance ID
string newInstanceId = await client.RestartInstanceAsync(instanceId, restartWithNewInstanceId: true);
Console.WriteLine($"Restarted as new instance: {newInstanceId}");

// Restart an orchestration keeping the same instance ID
await client.RestartInstanceAsync(instanceId, restartWithNewInstanceId: false);

Rensa orkestreringsinstanshistorik

Om du vill ta bort alla data som är associerade med en orkestrering rensar du instanshistoriken. Ta till exempel bort alla lagringsresurser som är associerade med en slutförd instans. Använd den purge instance API som definierats av orkestreringsklienten.

I följande exempel visas hur du rensar en enda orkestreringsinstans.

Isolerad arbetsmodell
[Function("PurgeInstanceHistory")]
public static async Task Run(
    [DurableClient] DurableTaskClient client,
    [QueueTrigger("purge-queue")] string instanceId)
{
    await client.PurgeInstanceAsync(instanceId);
}

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

using Microsoft.DurableTask.Client;

// Purge a single orchestration instance
PurgeResult result = await client.PurgeInstanceAsync(instanceId);
Console.WriteLine($"Purged {result.PurgedInstanceCount} instance(s).");

I följande exempel visas en timerutlöst funktion som rensar bort historiken för alla orkestreringsinstanser som avslutades innan det angivna tidsintervallet. I det här fallet tar den bort data för alla instanser som slutfördes för 30 eller fler dagar sedan. Den här exempelfunktionen är schemalagd att köras en gång per dag kl. 12:00 UTC:

Isolerad arbetsmodell
[Function("PurgeInstanceHistory")]
public static async Task Run(
    [DurableClient] DurableTaskClient client,
    [TimerTrigger("0 0 12 * * *")] TimerInfo myTimer)
{
    var filter = new PurgeInstancesFilter(
        CreatedFrom: DateTime.MinValue,
        CreatedTo: DateTime.UtcNow.AddDays(-30),
        Statuses: new[] { OrchestrationRuntimeStatus.Completed });

    await client.PurgeAllInstancesAsync(filter);
}

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

using Microsoft.DurableTask.Client;

// Purge completed instances older than 30 days
var filter = new PurgeInstancesFilter(
    CreatedFrom: DateTime.MinValue,
    CreatedTo: DateTime.UtcNow.AddDays(-30),
    Statuses: new[] { OrchestrationRuntimeStatus.Completed });

PurgeResult result = await client.PurgeAllInstancesAsync(filter);
Console.WriteLine($"Purged {result.PurgedInstanceCount} instance(s).");

Anmärkning

För att rensningshistoriken ska lyckas måste körningsstatusen för målinstansen vara Slutförd, Avslutad eller Misslyckad.

Nästa steg