Dela via


Begärandekontext

RequestContext Är en Orleans funktion som gör att programmetadata, till exempel ett spårnings-ID, kan flöda med begäranden. Programmetadata kan läggas till på klienten. den flödar med Orleans begäranden till det mottagande kornet. Funktionen implementeras av en offentlig statisk klass, RequestContext, i Orleans namnområdet. Den här klassen exponerar två enkla metoder:

void Set(string key, object value)

Föregående API används för att lagra ett värde i begärandekontexten. Värdet kan vara valfri serialiserbar typ.

object Get(string key)

Föregående API används för att hämta ett värde från den aktuella begärandekontexten.

Säkerhetskopieringslagringen för RequestContext är asynkron.lokal. När en anropare (oavsett om det är på klientsidan eller inom Orleans) skickar en begäran inkluderas innehållet i anroparens RequestContext med Orleans meddelandet för begäran. När kornkoden tar emot begäran är dessa metadata tillgängliga från den lokala RequestContext. Om kornkoden inte ändrar RequestContext, kommer alla korn som den begär att få samma metadata och så vidare.

Programmetadata underhålls också när du schemalägger en framtida beräkning med eller StartNew ContinueWith. I båda fallen körs fortsättningen med samma metadata som schemaläggningskoden hade när beräkningen schemalagts (det vill säga systemet gör en kopia av aktuella metadata och skickar den till fortsättningen, så ändringar efter anropet till StartNew eller ContinueWith kommer inte att ses av fortsättningen).

Viktigt!

Programmetadata flödar inte tillbaka med svar. Det vill säga att kod som körs som ett resultat av att ett svar tas emot, antingen inom en ContinueWith fortsättning eller efter ett anrop till Task.Wait() eller GetValue, fortfarande körs inom den aktuella kontext som angavs av den ursprungliga begäran.

Om du till exempel vill ange ett spårnings-ID i klienten till ett nytt Guidanropar du:

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

Inom kornkod (eller annan kod som körs i Orleans en scheduler-tråd) kan spårnings-ID:t för den ursprungliga klientbegäran användas, till exempel när du skriver en logg:

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

Även om alla serialiserbara object objekt kan skickas som programmetadata är det värt att nämna att stora eller komplexa objekt kan lägga till märkbara omkostnader för meddelandeserialiseringstiden. Därför rekommenderas användning av enkla typer (strängar, GUID:er eller numeriska typer).

Exempel på kornkod

För att illustrera användningen av en begärandekontext bör du överväga följande exempel på kornkod:

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);
}

Metoden SayHello loggar den inkommande greeting parametern och hämtar sedan spårnings-ID:t från begärandekontexten. Om inget spårnings-ID hittas loggar kornigheten "Inget spårnings-ID".

Exempelklientkod

Klienten kan ange spårnings-ID:t i begärandekontexten innan metoden SayHello anropas på HelloGrain. Följande klientkod visar hur du anger ett spårnings-ID i begärandekontexten och anropar SayHello metoden på 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!

I det här exemplet anger klienten spårnings-ID till "example-id-set-by-client" innan metoden SayHello anropas HelloGrainpå . Kornet hämtar spårnings-ID:t från begärandekontexten och loggar det.