Compartilhar via


Contexto da solicitação

O RequestContext é um recurso do Orleans que permite que metadados de aplicativos, como uma ID de rastreamento, fluam com solicitações. Os metadados de aplicativos podem ser adicionados ao cliente. Eles fluirá com solicitações do Orleans para a granularidade receptora. 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)

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 é local assíncrono. Quando um chamador (seja do lado do cliente ou dentro do Orleans) envia uma solicitação, o conteúdo do RequestContext chamador é incluído com a mensagem do Orleans para a solicitação. Quando o código de granularidade recebe a solicitação, esses metadados ficam acessíveis no RequestContext local. Se o código de granularidade não modificar o RequestContext, qualquer granularidade que ele solicitar receberá os mesmos metadados e assim por diante.

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 será executada com os mesmos metadados que o código de agendamento tinha no momento em que a computação foi agendada (ou seja, o sistema faz uma cópia dos metadados atuais e os passa para a continuação e, assim, as alterações após a chamada para StartNew ou ContinueWith não serão vistas pela continuação).

Importante

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

Por exemplo, para definir uma ID de rastreamento no cliente como um novo Guid, chame:

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

No código de granularidade (ou em outro código executado no Orleans em um thread do agendador), a ID de rastreamento da solicitação do cliente original pode ser usada, por exemplo, ao gravar um log:

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

Embora qualquer serializável object possa ser enviado 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, é recomendável 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 de um contexto de solicitação, considere o seguinte exemplo de código de granulação:

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, a granulação registrará "Sem ID de rastreamento".

Exemplo de código do cliente

O cliente pode definir a ID de rastreamento no contexto da 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. A granulação recupera a ID de rastreamento do contexto da solicitação e a registra.