Udostępnij za pośrednictwem


Kontekst żądania

Jest RequestContext to Orleans funkcja, która umożliwia przepływ metadanych aplikacji, takich jak identyfikator śledzenia, z żądaniami. Metadane aplikacji można dodać na kliencie; przepływa 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)

Powyższy interfejs API służy do przechowywania wartości w kontekście żądania. Wartość może być dowolnym typem z możliwością serializacji.

object Get(string key)

Powyższy interfejs API służy do pobierania wartości z bieżącego kontekstu żądania.

Magazyn zapasowy dla RequestContext programu to async-local. Gdy obiekt wywołujący (niezależnie od tego, czy po stronie klienta, czy wewnątrz Orleans) wysyła żądanie, zawartość obiektu wywołującego RequestContext jest dołączona do komunikatu Orleans żądania; gdy kod ziarna odbiera żądanie, metadane są dostępne z lokalnego RequestContextobiektu . Jeśli kod ziarna nie modyfikuje RequestContextelementu , wszelkie ziarna, które żąda, będą odbierać te same metadane itd.

Metadane aplikacji są również zachowywane podczas planowania przyszłych obliczeń przy użyciu metody StartNew lub ContinueWith; w obu przypadkach kontynuacja będzie wykonywana z tymi samymi metadanymi, co kod planowania miał w momencie zaplanowania obliczeń (czyli system tworzy kopię bieżących metadanych i przekazuje je do kontynuacji, więc zmiany po wywołaniu metody StartNew lub ContinueWith nie będą widoczne przez kontynuację).

Ważne

Metadane aplikacji nie przepływają z powrotem z odpowiedziami; oznacza to, że kod uruchamiany w wyniku odebrania odpowiedzi w ramach ContinueWith kontynuacji lub po wywołaniu metody Task.Wait() lub GetValuenadal będzie uruchamiany w bieżącym kontekście ustawionym przez oryginalne żądanie.

Aby na przykład ustawić identyfikator śledzenia w kliencie na nowy Guidelement , należy wywołać następujące wywołanie:

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

W kodzie ziarna (lub innym kodzie uruchamianym w wątku Orleans harmonogramu) można użyć identyfikatora śledzenia oryginalnego żądania klienta, na przykład podczas pisania dziennika:

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

Chociaż wszelkie serializacji object mogą być wysyłane jako metadane aplikacji, warto wspomnieć, że duże lub złożone obiekty mogą dodać zauważalne obciążenie do czasu serializacji komunikatów. Z tego powodu zalecane jest użycie prostych typów (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 SayHello metody w HelloGrainpliku . Poniższy kod klienta pokazuje, jak ustawić identyfikator śledzenia w kontekście żądania i wywołać metodę SayHello w pliku 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 SayHello metody w HelloGrainobiekcie . Ziarno pobiera identyfikator śledzenia z kontekstu żądania i rejestruje go.