Udostępnij przez


Kontekst żądania

RequestContext to funkcja Orleans umożliwiająca przepływ metadanych aplikacji, takich jak identyfikator śledzenia, wraz z żądaniami. Metadane aplikacji można dodawać na kliencie; przepływają z żądaniami Orleans do ziarna odbierającego. Funkcja jest implementowana przez publiczną klasę statyczną , RequestContextw Orleans przestrzeni nazw. Ta klasa uwidacznia dwie proste metody:

void Set(string key, object value)

Użyj powyższego interfejsu API, aby zapisać wartość w kontekście żądania. Wartość może być dowolnym typem z możliwością serializacji.

object Get(string key)

Użyj powyższego interfejsu API, aby pobrać wartość z bieżącego kontekstu żądania.

Magazyn zapasowy dla RequestContext programu to async-local. Gdy obiekt wywołujący (po stronie klienta lub wewnątrz Orleans) wysyła żądanie, zawartość obiektu wywołującego RequestContext jest dołączona do Orleans wiadomości dla żądania. Gdy kod ziarna odbiera żądanie, metadane są dostępne z lokalnego RequestContext. Jeśli kod ziarna nie modyfikuje RequestContext, wtedy każde ziarno w prośbie otrzymuje te same metadane itd.

Metadane aplikacji są również zachowywane podczas planowania przyszłych obliczeń przy użyciu polecenia StartNew lub ContinueWith. W obu przypadkach kontynuacja jest wykonywana z tymi samymi metadanymi, jakie kod harmonogramowania miał w momencie harmonogramowania obliczeń. Oznacza to, że system kopiuje bieżące metadane i przekazuje je do kontynuacji, więc kontynuacja nie będzie widzieć zmian wprowadzonych po wywołaniu metody StartNew lub ContinueWith.

Ważne

Metadane aplikacji nie przepływają z powrotem z odpowiedziami. Kod uruchamiany w wyniku otrzymania odpowiedzi (czy to w ramach kontynuacji ContinueWith, czy po wywołaniu Task.Wait() lub GetValue) nadal działa w bieżącym kontekście ustalonym przez oryginalne żądanie.

Aby na przykład ustawić identyfikator śledzenia w kliencie na nowy Guid, wywołaj:

RequestContext.Set("TraceId", Guid.NewGuid());

W kodzie wykonywanym w ramach obszaru działania (lub innym kodzie uruchomionym w wątku harmonogramu), można użyć identyfikatora śledzenia oryginalnego żądania klienta, na przykład podczas rejestrowania:

Logger.LogInformation(
    "Currently processing external request {TraceId}",
    RequestContext.Get("TraceId"));

Chociaż można wysyłać dowolne serializowalne object jako metadane aplikacji, warto wspomnieć, że duże lub złożone obiekty mogą znacznie wydłużyć czas serializacji komunikatów. Z tego powodu zalecamy używanie typów prostych (ciągów, identyfikatorów GUID lub typów liczbowych).

Przykładowy kod ziarna

Aby ułatwić zilustrowanie użycia kontekstu żądania, rozważmy następujący przykładowy kod ziarna:

using GrainInterfaces;
using Microsoft.Extensions.Logging;

namespace Grains;

public class HelloGrain(ILogger<HelloGrain> logger) : Grain, IHelloGrain
{
    ValueTask<string> IHelloGrain.SayHello(string greeting)
    {
        _logger.LogInformation("""
            SayHello message received: greeting = "{Greeting}"
            """,
            greeting);

        var traceId = RequestContext.Get("TraceId") as string
            ?? "No trace ID";

        return ValueTask.FromResult($"""
            TraceID: {traceId}
            Client said: "{greeting}", so HelloGrain says: Hello!
            """);
    }
}

public interface IHelloGrain : IGrainWithStringKey
{
    ValueTask<string> SayHello(string greeting);
}

Metoda SayHello rejestruje parametr przychodzący greeting , a następnie pobiera identyfikator śledzenia z kontekstu żądania. Jeśli nie znaleziono identyfikatora śledzenia, dzienniki ziarna "Brak identyfikatora śledzenia".

Przykładowy kod klienta

Klient może ustawić identyfikator śledzenia w kontekście żądania przed wywołaniem metody SayHello na HelloGrain. Poniższy kod klienta pokazuje, jak ustawić identyfikator śledzenia w kontekście żądania i wywołać metodę SayHello na HelloGrain.

using GrainInterfaces;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

using var host = Host.CreateDefaultBuilder(args)
    .UseOrleansClient(clientBuilder =>
        clientBuilder.UseLocalhostClustering())
    .Build();

await host.StartAsync();

var client = host.Services.GetRequiredService<IClusterClient>();

var grain = client.GetGrain<IHelloGrain>("friend");

var id = "example-id-set-by-client";

RequestContext.Set("TraceId", id);

var message = await friend.SayHello("Good morning!");

Console.WriteLine(message);
// Output:
//   TraceID: example-id-set-by-client
//   Client said: "Good morning!", so HelloGrain says: Hello!

W tym przykładzie klient ustawia identyfikator śledzenia na "example-id-set-by-client" przed wywołaniem metody SayHello w obiekcie HelloGrain. Ziarno pobiera identyfikator śladu z kontekstu żądania i loguje go.