Kontext požadavku
Jedná se RequestContext o Orleans funkci, která umožňuje tok metadat aplikace, jako je ID trasování, s požadavky. V klientovi mohou být přidána metadata aplikace; bude tok s Orleans požadavky na přijímající agregační interval. Funkce je implementována veřejnou statickou třídou , RequestContext
v Orleans oboru názvů. Tato třída zveřejňuje dvě jednoduché metody:
void Set(string key, object value)
Předchozí rozhraní API slouží k uložení hodnoty v kontextu požadavku. Hodnota může být libovolný serializovatelný typ.
object Get(string key)
Předchozí rozhraní API slouží k načtení hodnoty z kontextu aktuálního požadavku.
Záložní úložiště pro RequestContext
je async-local. Když volající (ať už na straně klienta nebo v rámci Orleans) odešle požadavek, obsah volajícího RequestContext
se zahrne do Orleans zprávy požadavku. Když kód zrnka obdrží požadavek, budou tato metadata přístupná z místního RequestContext
prostředí . Pokud kód odstupňova neupraví RequestContext
kód , pak jakékoli odstupňované požadavky na přijetí stejných metadat atd.
Metadata aplikace se také udržují, když plánujete budoucí výpočet pomocí StartNew nebo ContinueWith; v obou případech se pokračování provede se stejnými metadaty jako plánovací kód v okamžiku, kdy byl výpočet naplánován (to znamená, že systém vytvoří kopii aktuálních metadat a předá ho pokračování, takže změny po volání StartNew
nebo ContinueWith
nebudou vidět pokračováním).
Důležité
Metadata aplikace nedochází zpět s odpověďmi; to znamená, že kód, který se spustí v důsledku přijetí odpovědi, buď v rámci ContinueWith
pokračování, nebo po volání Task.Wait() nebo GetValue
, bude stále spuštěn v aktuálním kontextu, který byl nastaven původní požadavek.
Pokud chcete například nastavit ID trasování v klientovi na nový Guid
, zavoláte:
RequestContext.Set("TraceId", Guid.NewGuid());
V rámci odstupňovaného kódu (nebo jiného kódu, který běží ve Orleans vlákně plánovače), se dá použít ID trasování původního požadavku klienta, například při zápisu protokolu:
Logger.LogInformation(
"Currently processing external request {TraceId}",
RequestContext.Get("TraceId"));
I když se dá serializovat object
jako metadata aplikace, stojí za zmínku, že velké nebo složité objekty můžou znamenat výrazné režijní náklady na čas serializace zpráv. Z tohoto důvodu se doporučuje použití jednoduchých typů (řetězců, identifikátorů GUID nebo číselných typů).
Příklad kódu odstupňovaného kódu
Pokud chcete ilustrovat použití kontextu požadavku, zvažte následující příklad kódu agregace:
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
zaznamená příchozí greeting
parametr a pak načte ID trasování z kontextu požadavku. Pokud se nenajde žádné ID trasování, protokoluje protokol "Žádné ID trasování".
Příklad klientského kódu
Klient může před voláním SayHello
metody v HelloGrain
kontextu požadavku nastavit ID trasování v kontextu požadavku . Následující kód klienta ukazuje, jak nastavit ID trasování v kontextu požadavku a volat metodu SayHello
HelloGrain
na:
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!
V tomto příkladu klient nastaví ID trasování na example-id-set-by-client před voláním SayHello
metody na HelloGrain
. Agregační interval načte ID trasování z kontextu požadavku a protokoluje ho.