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.