请求上下文

RequestContext 是 Orleans 的一项功能,它使应用程序元数据(例如跟踪 ID)能够与请求一起流动。 可以在客户端添加应用程序元数据;它们将与 Orleans 请求一起流向接收方 grain。 该功能由 Orleans 命名空间中的公共静态类 RequestContext 实现。 此类公开两个简单方法:

void Set(string key, object value)

上面的 API 用于在请求上下文中存储一个值。 该值可以是任何可序列化类型。

Object Get(string key)

上面的 API 用于从当前请求上下文中检索一个值。

RequestContext 的后备存储是异步本地存储。 当某个调用方(不管是客户端还是 Orleans 内部)发送请求时,调用方的 RequestContext 的内容将包含在该请求的 Orleans 消息中;当 grain 代码接收请求时,可以从本地 RequestContext 访问该元数据。 如果 grain 代码未修改 RequestContext,则它请求的任何 grain 都将收到相同的元数据,依此类推。

当使用 StartNewContinueWith 计划将来的计算时,也会保留应用程序元数据;在这两种情况下,延续将使用计划代码在计划计算时具有的相同元数据来执行(也就是说,系统会复制当前元数据并将其传递给延续,因此在调用 StartNewContinueWith 后,延续不会看到更改)。

重要

应用程序元数据不会随响应一起流回;也就是说,由于接收响应(在 ContinueWith 延续中或者在调用 Task.Wait()GetValue 之后)而运行的代码仍将在原始请求设置的当前上下文中运行。

例如,若要将客户端中的跟踪 ID 设置为新的 Guid,只需调用:

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

在 grain 代码(或者在 Orleans 中的计划程序线程上运行的其他代码)中,可以使用原始客户端请求的跟踪 ID,例如,在写入日志时:

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

虽然任何可序列化对象都可以作为应用程序元数据发送,但值得一提的是,大型或复杂对象可能会显著增加消息序列化时的开销。 因此,建议使用简单类型(字符串、GUID 或数字类型)。