RequestContext는 Orleans 기능으로, 추적 ID와 같은 애플리케이션 메타데이터가 요청과 함께 흐르도록 허용합니다. 클라이언트에서 애플리케이션 메타데이터를 추가할 수 있으며, 요청과 함께 수신 그레인으로 전달됩니다. 기능은 RequestContext
네임스페이스에서 공용 정적 클래스 Orleans에 의해 구현됩니다. 이 클래스는 두 가지 간단한 메서드를 노출합니다.
void Set(string key, object value)
이전 API를 사용하여 요청 컨텍스트에 값을 저장합니다. 값은 직렬화 가능한 모든 형식일 수 있습니다.
object Get(string key)
이전 API를 사용하여 현재 요청 컨텍스트에서 값을 검색합니다.
RequestContext
백업 스토리지는 비동기 로컬입니다. 호출자(클라이언트 쪽 또는 Orleans 내부에서)가 요청을 보내면, 호출자의 RequestContext
내용이 요청에 대한 Orleans 메시지에 포함됩니다. 곡물 코드가 요청을 받으면 로컬 RequestContext
에서 해당 메타데이터에 액세스할 수 있습니다. 그레인 코드가 RequestContext
을 수정하지 않으면, 요청하는 모든 그레인이 동일한 메타데이터를 받습니다.
애플리케이션 메타데이터는 StartNew 또는 ContinueWith을 사용하여 향후 계산을 예약할 때도 유지됩니다. 두 경우 모두 연속 작업은 계산이 예약되었을 때 예약 코드와 동일한 메타데이터로 실행됩니다. 즉, 시스템은 현재 메타데이터를 복사하여 연속 작업에 전달합니다. 따라서 StartNew
또는 ContinueWith
호출 후에 이루어진 변경 사항은 연속 작업에서 보이지 않습니다.
중요합니다
애플리케이션 메타데이터는 응답과 함께 다시 흐르지 않습니다. 응답을 받은 결과( ContinueWith
에서 이어지는 경우 또는 Task.Wait()나 GetValue
에 대한 호출 이후에)로 실행되는 코드는 원래 요청에서 설정한 현재 컨텍스트 내에서 계속 실행됩니다.
예를 들어 클라이언트의 추적 ID를 새 Guid
ID로 설정하려면 다음을 호출합니다.
RequestContext.Set("TraceId", Guid.NewGuid());
예를 들어, 로그를 작성할 때 곡물 코드(또는 스케줄러 스레드에서 실행되는 다른 코드) 내에서 Orleans 원래 클라이언트 요청의 추적 ID를 사용할 수 있습니다.
Logger.LogInformation(
"Currently processing external request {TraceId}",
RequestContext.Get("TraceId"));
당신은 직렬화 가능한 object
를 애플리케이션 메타데이터로 보낼 수 있지만, 크거나 복잡한 개체는 메시지 직렬화 시간에 눈에 띄는 오버헤드를 추가할 수 있다는 점을 유의할 필요가 있습니다. 이러한 이유로 간단한 형식(문자열, GUID 또는 숫자 형식)을 사용하는 것이 좋습니다.
예제 곡물 코드
요청 컨텍스트의 사용을 설명하는 데 도움이 되도록 다음 예제 곡물 코드를 고려하세요.
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);
}
이 메서드는 SayHello
들어오는 greeting
매개 변수를 기록한 다음 요청 컨텍스트에서 추적 ID를 검색합니다. 추적 ID가 없으면 그레인은 "추적 ID 없음"을 기록합니다.
예제 클라이언트 코드
클라이언트는 SayHello
에서 HelloGrain
메서드를 호출하기 전에 요청 컨텍스트에서 추적 ID를 설정할 수 있습니다. 다음 클라이언트 코드는 요청 컨텍스트에서 추적 ID를 설정하고 SayHello
에 대한 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!
이 예제에서 클라이언트는 SayHello
의 HelloGrain
메서드를 호출하기 전에 "example-id-set-by-client"로 추적 ID를 설정합니다. 그레인은 요청 컨텍스트에서 추적 ID를 검색하고 기록합니다.
.NET