Egyéni orchestration állapot beállítása és lekérdezése

Az egyéni vezénylési állapot lehetővé teszi, hogy tetszőleges JSON-metaadatokat csatoljon egy futó vezénylési példányhoz, hogy a külső ügyfelek bármikor lekérdezhessenek. Használjon egyéni állapotot, amikor szüksége van rá:

  • Jelentéskészítés a repülés közben – a felhasználói felület megjelenítheti, hogy egy vezénylés melyik lépését érte el anélkül, hogy megvárta volna a befejezést.
  • Dinamikus adatokat ad vissza a hívóknak – felületi javaslatok, kedvezményadatok vagy következő lépésben megadott utasítások, miközben a vezénylés még fut.
  • Koordinálja a külső rendszerekkel – ossza meg azokat az állapotokat, amelyeket más szolgáltatások vagy emberi operátorok lekérhetnek és felhasználhatnak.

Figyelmeztetés

Az egyéni állapot terhelhetősége legfeljebb 16 KB UTF-16 JSON-szövegre korlátozódik. Ha nagyobb hasznos adatra van szüksége, használjon külső tárolót, és tároljon egy hivatkozást (például egy blob URL-címét) az egyéni állapotban.

Az Azure Functions esetében ez az állapot a HTTP GetStatus API vagy az egyenértékű SDK API révén érhető el az orchestration ügyfélobjektumon.

A Durable Task SDK-kban ez az állapot a DurableTaskClient vezénylési állapot lekérdezési API-jaival érhető el (például GetInstanceAsync .NET vagy getInstanceMetadata Java).

Fontos

A PowerShell Durable Task SDK jelenleg nem érhető el.

Mintahasználati esetek egyéni vezénylési állapothoz

Az alábbi táblázat a gyakori mintákat foglalja össze. Válasszon ki egy használati esetet a megfelelő példához való ugráshoz.

Felhasználási eset Leírás
Vezénylési folyamat vizualizációja Minden tevékenység után frissítsen egy sztringet vagy objektumot, hogy az ügyfelek megjeleníthessenek egy állapotjelzőt.
Dinamikus metaadatok visszaadva az ügyfeleknek Állítsa be a strukturált adatokat (például javaslatokat), amelyeket az ügyfelek egyéni kiszolgálóoldali végpontok nélkül renderelnek.
Végrehajtható adatok biztosítása az ügyfelek számára Mutasd meg a foglalási URL-eket, a kedvezményadatokat vagy a különböző lépésekben megjelenő utasításokat, amelyek alapján az ügyfelek cselekszenek, miközben az orchesztráció egy külső eseményre vár.
Egyéni állapot lekérdezése Olvassa el az egyéni állapotértéket egy ügyféltől HTTP API-k vagy SDK-hívások használatával.

Orchesztáció előrehaladásának vizualizálása

Ebben a mintában az orchestrator az egyes tevékenységek befejeződése után meghívja a SetCustomStatus (vagy a saját nyelvén megfelelője) komponenst, és az állapotot az utoljára befejezett város nevére frissíti. Az ügyfél lekérdezi az állapotvégpontot, beolvassa az aktuális értéket, és frissíti a folyamatjelzőt a felhasználói felületen.

Az alábbi minta a Durable Functions HTTP-állapotvégpont használatával mutatja be a folyamatmegosztást:

Megjegyzés:

Ezek a példák Durable Functions 2.x-hez vannak megírva, és nem kompatibilisek az 1.x Durable Functions. A verziók közötti különbségekről további információt a Durable Functions verzióiról szóló cikkben talál.

[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}!";
}

Az alábbi minta a Durable Task SDK ügyfél API-kkal való előrehaladás megosztását mutatja be:

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

Az ügyfél lekérdezheti az orchestration metaadatait, és megvárhatja, amíg a CustomStatus mező "London" állapotba kerül.

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

Az alábbi ügyfélkód lekérdezi az orchestráció állapotát, és megvárja, amíg CustomStatus nem kerül beállításra "London"-re a válasz visszaadása előtt.

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

Dinamikus metaadatok visszaadva az ügyfeleknek

Az egyéni vezénylési állapot használatával strukturált adatokat – például személyre szabott javaslatokat – adhat vissza az ügyfeleknek anélkül, hogy külön végpontokat hoz létre. Az orchestrátor a bemenet alapján állítja be a különálló állapotot, és az ügyfél a standard állapot API-n keresztül olvassa be. Így az ügyféloldali kód általános marad, míg az összes logika a kiszolgáló oldalán marad.

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

Végrehajtható adatok biztosítása az ügyfelek számára

Ebben a mintában a vezénylő időérzékeny információkat – például kedvezményt, foglalási URL-címet és időtúllépést – jelenít meg egyéni állapotként, majd várakozik egy külső eseményre. Az ügyfél felolvassa az egyéni állapotot az ajánlat megjelenítéséhez, és a megerősítő eseményt visszaküldi a vezénylőnek, amikor a felhasználó cselekszik.

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

Egyéni vezénylési állapot lekérdezése

Az előző példák bemutatják, hogyan állíthat be egyéni állapotot a vezénylőkódból. Ez a szakasz arra összpontosít, hogy a külső ügyfelek hogyan olvassák be ezt az értéket.

Miután egy vezénylő meghívja SetCustomStatus, a külső ügyfelek lekérdezhetik az értéket a beépített Durable Functions HTTP API-n keresztül. Például:

GET /runtime/webhooks/durabletask/instances/instance123

A válasz tartalmazza a mezőt a customStatus futtatókörnyezet metaadatai mellett:

{
  "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"
}

Az egyéni állapotot programozott módon is lekérdezheti a vezénylési ügyféloldali SDK használatával. A teljes hivatkozásért tekintse meg a lekérdezéspéldányokat.

A tartós feladat SDK-k nem biztosítanak beépített HTTP-állapotvégpontot. Ehelyett az egyéni állapotot programozottan kérdezheti le a vezénylési példány metaadat API-jainak használatával a DurableTaskClient.

using Microsoft.DurableTask.Client;

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

Figyelmeztetés

Az egyéni állapot terhelhetősége legfeljebb 16 KB UTF-16 JSON-szövegre korlátozódik.

Következő lépések