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ą , RequestContext
w 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 RequestContext
obiektu . Jeśli kod ziarna nie modyfikuje RequestContext
elementu , 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 GetValue
nadal będzie uruchamiany w bieżącym kontekście ustawionym przez oryginalne żądanie.
Aby na przykład ustawić identyfikator śledzenia w kliencie na nowy Guid
element , 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 HelloGrain
pliku . 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 HelloGrain
obiekcie . Ziarno pobiera identyfikator śledzenia z kontekstu żądania i rejestruje go.