Sdílet prostřednictvím


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 , RequestContextv 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 RequestContextprostředí . Pokud kód odstupňova neupraví RequestContextkó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 HelloGrainkontextu 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 HelloGrainna:

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.