Partilhar via


Contexto da solicitação

O RequestContext é um Orleans recurso que permite que metadados de aplicativos, como uma ID de rastreamento, fluam com solicitações. Os metadados da aplicação podem ser adicionados no cliente; ele fluirá com Orleans pedidos para o grão recetor. O recurso é implementado por uma classe estática pública, RequestContext, no Orleans namespace. Esta classe expõe dois métodos simples:

void Set(string key, object value)

A API anterior é usada para armazenar um valor no contexto de solicitação. O valor pode ser qualquer tipo serializável.

object Get(string key)

A API anterior é usada para recuperar um valor do contexto de solicitação atual.

O armazenamento de backup para RequestContext é async-local. Quando um chamador (seja do lado do cliente ou dentro Orleans) envia uma solicitação, o conteúdo do chamador RequestContext é incluído com a Orleans mensagem para a solicitação, quando o código grain recebe a solicitação, esses metadados são acessíveis a partir do local RequestContext. Se o código de grão não modificar o RequestContext, então qualquer grão que ele solicitar receberá os mesmos metadados e assim por diante.

Os metadados do aplicativo também são mantidos quando você agenda um cálculo futuro usando StartNew ou ContinueWith; em ambos os casos, a continuação será executada com os mesmos metadados que o código de agendamento tinha no momento em que o cálculo foi agendado (ou seja, o sistema faz uma cópia dos metadados atuais e os passa para a continuação, portanto, muda após a chamada para StartNew ou ContinueWith não será visto pela continuação).

Importante

Os metadados do aplicativo não fluem de volta com as respostas; ou seja, o código que é executado como resultado de uma resposta que está sendo recebida, seja dentro de uma ContinueWith continuação ou após uma chamada para Task.Wait() ou GetValue, ainda será executado dentro do contexto atual que foi definido pela solicitação original.

Por exemplo, para definir uma id de rastreamento no cliente como um novo Guid, você chama:

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

Dentro do código grain (ou outro código executado em Orleans um thread do agendador), a id de rastreamento da solicitação do cliente original pode ser usada, por exemplo, ao escrever um log:

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

Embora qualquer serializável object possa ser enviado como metadados de aplicativo, vale a pena mencionar que objetos grandes ou complexos podem adicionar sobrecarga percetível ao tempo de serialização de mensagens. Por esse motivo, recomenda-se o uso de tipos simples (strings, GUIDs ou tipos numéricos).

Exemplo de código de grão

Para ajudar a ilustrar o uso de um contexto de solicitação, considere o seguinte código de grão de exemplo:

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

O SayHello método registra o parâmetro de entrada greeting e, em seguida, recupera a id de rastreamento do contexto da solicitação. Se nenhuma id de rastreamento for encontrada, os logs de grão "Sem ID de rastreamento".

Exemplo de código de cliente

O cliente é capaz de definir a id de rastreamento no contexto da solicitação antes de chamar o SayHello método no HelloGrain. O código de cliente a seguir demonstra como definir uma id de rastreamento no contexto da solicitação e chamar o SayHello método no 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!

Neste exemplo, o cliente define a id de rastreamento como "example-id-set-by-client" antes de chamar o SayHello método no HelloGrain. O grão recupera o id de rastreamento do contexto da solicitação e o registra.