Compartilhar via


Contexto da solicitação

RequestContext é um recurso Orleans que permite que metadados do aplicativo, como um ID de rastreamento, fluam com as solicitações. Você pode adicionar metadados do aplicativo ao cliente; ele é enviado junto com Orleans solicitações para o grão destinatário. O recurso é implementado por uma classe estática pública, RequestContext, no namespace do Orleans. Essa classe expõe dois métodos simples:

void Set(string key, object value)

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

object Get(string key)

Use a API anterior para recuperar um valor do contexto de solicitação atual.

O armazenamento de backup para RequestContext é local assíncrono. Quando um chamador (do lado do cliente ou de dentro Orleans) envia uma solicitação, o conteúdo do chamador é RequestContext incluído com a Orleans mensagem da solicitação. Quando o código de grão recebe a solicitação, esses metadados são acessíveis do local RequestContext. Se o código do grão não modificar o RequestContext, qualquer grão solicitado receberá os mesmos metadados, e assim sucessivamente.

Os metadados do aplicativo também são mantidos quando você agenda uma computação futura usando StartNew ou ContinueWith. Em ambos os casos, a continuação é executada com os mesmos metadados que o código de agendamento teve quando a computação foi agendada. Ou seja, o sistema copia os metadados atuais e os passa para a continuação, portanto, a continuação não verá alterações feitas após a chamada para StartNew ou ContinueWith.

Importante

Os metadados do aplicativo não são retornados com as respostas. O código que é executado como resultado do recebimento de uma resposta (dentro de uma ContinueWith continuação ou após uma chamada para Task.Wait() ou GetValue) ainda é executado dentro do contexto atual definido pela solicitação original.

Por exemplo, para definir uma ID de rastreamento no cliente para uma nova Guid, chame:

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

No código em grão (ou em outro código em execução dentro de Orleans em um thread do agendador), você pode usar a ID de rastreamento da solicitação do cliente original, por exemplo, ao escrever um log:

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

Embora você possa enviar qualquer serializável object como metadados do aplicativo, vale a pena mencionar que objetos grandes ou complexos podem adicionar sobrecarga perceptível ao tempo de serialização da mensagem. Por esse motivo, recomendamos o uso de tipos simples (cadeias de caracteres, GUIDs ou tipos numéricos).

Exemplo de código de granulação

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

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 recupera a ID de rastreamento do contexto da solicitação. Se nenhuma ID de rastreamento for encontrada, o grão registrará "Nenhuma ID de rastreamento".

Exemplo de código do cliente

O cliente pode definir a ID de rastreamento no contexto de solicitação antes de chamar o SayHello método no HelloGrain. O código do 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 a ID de rastreamento do contexto de solicitação e registra-a em log.