De status van aangepaste orkestratie instellen en er query's op uitvoeren

Met de aangepaste indelingsstatus kunt u willekeurige JSON-metagegevens koppelen aan een actief orchestration-exemplaar, zodat externe clients er op elk gewenst moment query's op kunnen uitvoeren. Gebruik de aangepaste status wanneer u het volgende moet doen:

  • Meld voortgang tijdens de vlucht. Laat een gebruikersinterface zien welke stap een orkestratie heeft bereikt zonder te wachten totdat deze is voltooid.
  • Retourneer dynamische gegevens naar aanroepers – geef aanbevelingen, kortingsinformatie of instructies voor de volgende stap weer terwijl de orkestratie nog steeds wordt uitgevoerd.
  • Coördinaat met externe systemen : deel de status waaraan andere services of menselijke operators kunnen peilen en erop kunnen reageren.

Waarschuwing

De payload van de aangepaste status is beperkt tot 16 KB UTF-16 JSON-tekst. Als u een grotere nettolading nodig hebt, gebruikt u externe opslag en slaat u in plaats daarvan een verwijzing (zoals een blob-URL) op in de aangepaste status.

In Azure Functions is deze status beschikbaar via de HTTP GetStatus-API of de equivalente SDK-API op het orchestration-clientobject.

In Durable Task SDK's is deze status beschikbaar via orchestratie status query API's op de DurableTaskClient (bijvoorbeeld GetInstanceAsync in .NET of getInstanceMetadata in Java).

Belangrijk

Momenteel is de Durable Task SDK van PowerShell niet beschikbaar.

Voorbeelden van use cases voor aangepaste orkestratiestatus

De volgende tabel bevat een overzicht van veelvoorkomende patronen. Selecteer een use-case om naar het bijbehorende voorbeeld te gaan.

Gebruiksituatie Beschrijving
Voortgang van orkestratie visualiseren Werk een tekenreeks of object bij zodat klanten na elke activiteit een voortgangsindicator kunnen weergeven.
Dynamische metagegevens retourneren aan clients Stel gestructureerde gegevens (zoals aanbevelingen) in die clients weergeven zonder aangepaste eindpunten aan de serverzijde te hoeven gebruiken.
Bruikbare gegevens leveren aan clients Surface boekings-URL's, kortingsinformatie of instructies voor de volgende stap waarop cliënten reageren terwijl de orchestratie wacht op een externe gebeurtenis.
Querystatus aanpassen Lees de aangepaste statuswaarde van een client met behulp van HTTP-API's of SDK-aanroepen.

Visualiseer orkestratievoortgang

In dit patroon roept de orchestrator SetCustomStatus aan (of het equivalent in uw taal) nadat elke activiteit is voltooid, waarbij de status wordt bijgewerkt met de naam van de laatst voltooide plaats. Een client controleert het statuseindpunt, leest de huidige waarde en werkt een voortgangsindicator bij in de gebruikersinterface.

In het volgende voorbeeld ziet u het delen van de voortgang met behulp van het Durable Functions HTTP-statuseindpunt:

Opmerking

Deze voorbeelden zijn geschreven voor Durable Functions 2.x en zijn niet compatibel met Durable Functions 1.x. Zie het artikel Durable Functions versies voor meer informatie over de verschillen tussen versies.

[FunctionName("E1_HelloSequence")]
public static async Task<List<string>> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();

    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Tokyo"));
    context.SetCustomStatus("Tokyo");
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Seattle"));
    context.SetCustomStatus("Seattle");
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "London"));
    context.SetCustomStatus("London");

    // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
    return outputs;
}

[FunctionName("E1_SayHello")]
public static string SayHello([ActivityTrigger] string name)
{
    return $"Hello {name}!";
}

In het volgende voorbeeld ziet u hoe u voortgang deelt met behulp van de Durable Task SDK-client-API's:

using System.Threading.Tasks;
using Microsoft.DurableTask;

public class HelloCities : TaskOrchestrator<object?, string>
{
    public override async Task<string> RunAsync(TaskOrchestrationContext context, object? input)
    {
        string result = "";

        result += await context.CallActivityAsync<string>("SayHello", "Tokyo") + ", ";
        context.SetCustomStatus("Tokyo");

        result += await context.CallActivityAsync<string>("SayHello", "London") + ", ";
        context.SetCustomStatus("London");

        result += await context.CallActivityAsync<string>("SayHello", "Seattle");
        context.SetCustomStatus("Seattle");

        return result;
    }
}

De client kan orkestratie-metadata peilen en wachten totdat het CustomStatus-veld op "London" is ingesteld:

using System.Threading.Tasks;
using Microsoft.DurableTask.Client;

string instanceId = await client.ScheduleNewOrchestrationInstanceAsync("HelloCities");

OrchestrationMetadata metadata = await client.WaitForInstanceStartAsync(instanceId, getInputsAndOutputs: true);
while (metadata.SerializedCustomStatus is null || metadata.ReadCustomStatusAs<string>() != "London")
{
    await Task.Delay(200);
    metadata = await client.GetInstanceAsync(instanceId, getInputsAndOutputs: true) ?? metadata;
}

Met de volgende clientcode wordt de orchestratiestatus gepeild en wordt er gewacht totdat CustomStatus op "London" is ingesteld voordat er een antwoord wordt geretourneerd.

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

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

    DurableOrchestrationStatus durableOrchestrationStatus = await starter.GetStatusAsync(instanceId);
    while (durableOrchestrationStatus.CustomStatus.ToString() != "London")
    {
        await Task.Delay(200);
        durableOrchestrationStatus = await starter.GetStatusAsync(instanceId);
    }

    HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK)
    {
        Content = new StringContent(JsonConvert.SerializeObject(durableOrchestrationStatus))
    };

    return httpResponseMessage;
  }
}

Dynamische metagegevens retourneren aan clients

U kunt de aangepaste indelingsstatus gebruiken om gestructureerde gegevens, zoals persoonlijke aanbevelingen, te retourneren aan clients zonder afzonderlijke eindpunten te bouwen. De orchestrator stelt de aangepaste status in op basis van invoer en de client leest deze via de standaardstatus-API. Hierdoor blijft code aan de clientzijde algemeen, terwijl alle logica aan de serverzijde blijft.

[FunctionName("CityRecommender")]
public static void Run(
  [OrchestrationTrigger] IDurableOrchestrationContext context)
{
  int userChoice = context.GetInput<int>();

  switch (userChoice)
  {
    case 1:
    context.SetCustomStatus(new
    {
      recommendedCities = new[] {"Tokyo", "Seattle"},
      recommendedSeasons = new[] {"Spring", "Summer"}
     });
      break;
    case 2:
      context.SetCustomStatus(new
      {
                recommendedCities = new[] {"Seattle", "London"},
        recommendedSeasons = new[] {"Summer"}
      });
        break;
      case 3:
      context.SetCustomStatus(new
      {
                recommendedCities = new[] {"Tokyo", "London"},
        recommendedSeasons = new[] {"Spring", "Summer"}
      });
        break;
  }

  // Wait for user selection and refine the recommendation
}
using System.Threading.Tasks;
using Microsoft.DurableTask;

public class CityRecommender : TaskOrchestrator<int, object?>
{
    public override Task<object?> RunAsync(TaskOrchestrationContext context, int userChoice)
    {
        switch (userChoice)
        {
            case 1:
                context.SetCustomStatus(new
                {
                    recommendedCities = new[] { "Tokyo", "Seattle" },
                    recommendedSeasons = new[] { "Spring", "Summer" },
                });
                break;
            case 2:
                context.SetCustomStatus(new
                {
                    recommendedCities = new[] { "Seattle", "London" },
                    recommendedSeasons = new[] { "Summer" },
                });
                break;
            case 3:
                context.SetCustomStatus(new
                {
                    recommendedCities = new[] { "Tokyo", "London" },
                    recommendedSeasons = new[] { "Spring", "Summer" },
                });
                break;
        }

        // Wait for user selection and refine the recommendation
        return Task.FromResult<object?>(null);
    }
}

Bruikbare gegevens leveren aan clients

In dit patroon geeft de orchestrator tijdgevoelige informatie weer, zoals korting, een boekings-URL en een time-out, via aangepaste status, en pauzeert vervolgens om te wachten op een externe gebeurtenis. Een client leest de aangepaste status om de aanbieding weer te geven en stuurt de bevestigings gebeurtenis terug naar de orchestrator wanneer de gebruiker handelt.

[FunctionName("ReserveTicket")]
public static async Task<bool> Run(
  [OrchestrationTrigger] IDurableOrchestrationContext context)
{
  string userId = context.GetInput<string>();

  int discount = await context.CallActivityAsync<int>("CalculateDiscount", userId);

  context.SetCustomStatus(new
  {
    discount = discount,
    discountTimeout = 60,
    bookingUrl = "https://www.myawesomebookingweb.com",
  });

  bool isBookingConfirmed = await context.WaitForExternalEvent<bool>("BookingConfirmed");

  context.SetCustomStatus(isBookingConfirmed
    ? new {message = "Thank you for confirming your booking."}
    : new {message = "The booking was not confirmed on time. Please try again."});

  return isBookingConfirmed;
}
using System.Threading.Tasks;
using Microsoft.DurableTask;

public class ReserveTicket : TaskOrchestrator<string, bool>
{
    public override async Task<bool> RunAsync(TaskOrchestrationContext context, string userId)
    {
        int discount = await context.CallActivityAsync<int>("CalculateDiscount", userId);

        context.SetCustomStatus(new
        {
            discount,
            discountTimeout = 60,
            bookingUrl = "https://www.myawesomebookingweb.com",
        });

        bool isBookingConfirmed = await context.WaitForExternalEvent<bool>("BookingConfirmed");
        context.SetCustomStatus(isBookingConfirmed
            ? new { message = "Thank you for confirming your booking." }
            : new { message = "The booking was not confirmed on time. Please try again." });

        return isBookingConfirmed;
    }
}

Status van aangepaste orkestratie opvragen

In de vorige voorbeelden ziet u hoe u aangepaste status instelt vanuit orchestratorcode. In deze sectie wordt uitgelegd hoe externe clients die waarde lezen.

Nadat een orchestrator SetCustomStatus aanroept, kunnen externe clients de waarde opvragen via de ingebouwde Durable Functions HTTP-API. Voorbeeld:

GET /runtime/webhooks/durabletask/instances/instance123

Het antwoord bevat het customStatus veld naast runtimemetagegevens:

{
  "runtimeStatus": "Running",
  "input": null,
  "customStatus": { "nextActions": ["A", "B", "C"], "foo": 2 },
  "output": null,
  "createdTime": "2019-10-06T18:30:24Z",
  "lastUpdatedTime": "2019-10-06T19:40:30Z"
}

U kunt ook programmatisch query's uitvoeren op aangepaste status met behulp van de orchestration-client-SDK. Zie Query-instanties voor een volledige referentie.

Durable Task SDK's bieden geen ingebouwd HTTP-statuseindpunt. In plaats daarvan vraagt u programmatisch de aangepaste status op met de metagegevens-API's van het orchestratie-exemplaar op de DurableTaskClient.

using Microsoft.DurableTask.Client;

OrchestrationMetadata? metadata = await client.GetInstanceAsync(instanceId, getInputsAndOutputs: true);
string? customStatusJson = metadata?.SerializedCustomStatus;

Waarschuwing

De payload van de aangepaste status is beperkt tot 16 KB UTF-16 JSON-tekst.

Volgende stappen