Compartir a través de


Contexto de solicitud

RequestContext es una Orleans característica que permite que los metadatos de la aplicación, como un identificador de seguimiento, se transmitan con las solicitudes. Puede agregar metadatos de aplicación en el cliente; estos se transmiten con las Orleans solicitudes a la unidad receptora. La característica se implementa mediante una clase estática pública, RequestContext, en el espacio de nombres de Orleans. Esta clase expone dos métodos simples:

void Set(string key, object value)

Use la API anterior para almacenar un valor en el contexto de solicitud. El valor puede ser cualquier tipo serializable.

object Get(string key)

Use la API anterior para recuperar un valor del contexto de solicitud actual.

El almacenamiento de respaldo para RequestContext es async-local. Cuando un llamante (en el lado del cliente o dentro de Orleans) envía una solicitud, el contenido del llamante RequestContext se incluye en el mensaje Orleans de la solicitud. Cuando el código de grains recibe la solicitud, los metadatos son accesibles desde la instancia local RequestContext. Si el código de grano no modifica el RequestContext, entonces cualquier grano que solicite recibe los mismos metadatos, y así sucesivamente.

Los metadatos de la aplicación también se mantienen cuando se programa un cálculo futuro mediante StartNew o ContinueWith. En ambos casos, la continuación se ejecuta con los mismos metadatos que el código de programación tenía cuando se programó el cálculo. Es decir, el sistema copia los metadatos actuales y lo pasa a la continuación, por lo que la continuación no verá los cambios realizados después de la llamada a StartNew o ContinueWith.

Importante

Los metadatos de la aplicación no se transmiten de vuelta con las respuestas. El código que se ejecuta como resultado de recibir una respuesta (ya sea dentro de una ContinueWith continuación o después de una llamada a Task.Wait() o GetValue) todavía se ejecuta dentro del contexto actual establecido por la solicitud original.

Por ejemplo, para establecer un identificador de seguimiento en el cliente en un nuevo Guid, llame a:

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

Dentro del código específico (u otro código que se ejecuta en Orleans un subproceso del programador), puede usar el identificador de seguimiento de la solicitud de cliente original, por ejemplo, al escribir un registro:

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

Aunque es posible enviar cualquier object serializable como metadatos de aplicación, merece la pena mencionar que los objetos grandes o complejos pueden agregar un sobrecoste considerable al tiempo de serialización de mensajes. Por este motivo, se recomienda usar tipos simples (cadenas, GUID o tipos numéricos).

Código de grano de ejemplo

Para ayudar a ilustrar el uso del contexto de solicitud, tenga en cuenta el siguiente código de grano de ejemplo:

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

El SayHello método registra el parámetro entrante greeting y, a continuación, recupera el identificador de seguimiento del contexto de solicitud. Si no se encuentra ningún identificador de seguimiento, el sistema registra "No se encontró ID de seguimiento".

Código de cliente de ejemplo

El cliente puede establecer el identificador de seguimiento en el contexto de la solicitud antes de llamar al método SayHello en HelloGrain. El código de cliente siguiente muestra cómo establecer un identificador de seguimiento en el contexto de solicitud y llamar al SayHello método en 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!

En este caso, el cliente establece el ID de traza en "example-id-set-by-client" antes de llamar al método SayHello en HelloGrain. El grano recupera el identificador de seguimiento del contexto de solicitud y lo registra.