go - 如何在拦截器中安全地将值添加到 grpc ServerStream
问题描述
我的 grpc 服务器有一个日志拦截器,并且想为元数据添加一个值(我想在请求的整个生命周期内跟踪请求):
func (m *middleware) loggingInterceptor(srv interface{},
ss grpc.ServerStream,
info *grpc.StreamServerInfo,
handler grpc.StreamHandler)
md, ok := metadata.FromIncomingContext(ss.Context())
if !ok {
return errors.New("could not get metadata from incoming stream context")
}
// add the transaction id to the metadata so that business logic can track it
md.Append("trans-id", "some-transaction-id")
// call the handler func
return handler(srv, ss)
}
但文档FromIncomingContext
声明:
// FromIncomingContext returns the incoming metadata in ctx if it exists. The
// returned MD should not be modified. Writing to it may cause races.
// Modification should be made to copies of the returned MD.
好的,所以我看一下复制功能并复制元数据:
mdCopy := md.Copy()
mdCopy.Append("trans-id", "some-transaction-id")
并想“我如何将这个元数据附加回ServerStream
上下文?”,然后我检查是否有一些ss.SetContext(newCtx)
,但我没有看到任何类似的东西。我是从错误的角度考虑这个问题,还是我错过了其他东西?
解决方案
您需要使用NewIncomingContext在流中创建当前上下文的副本。
然后,您必须创建一个wrappedStream
覆盖Context
方法 in的类型ServerStream
以返回修改后的context
. 您需要将其传递wrappedStream
给handler
您在拦截器中收到的。
你可以在这里看到一个例子(它在这里覆盖了其他方法,但想法是一样的): https ://github.com/grpc/grpc-go/blob/master/examples/features/interceptor/server/main .go#L106-L124
希望这可以帮助。
推荐阅读
- php - 如何在 behat 脚本中修复 behat 'DMore\ChromeDriver\StreamReadException'
- sqlite - 房间的日历类型转换器(Kotlin)
- authentication - .net core 2.1 中的多个 JWT 不记名身份验证 - 声明问题
- delphi - 有没有一种简单的方法可以使我的只读 TEdit 的设计与我禁用的 TEdit 的设计相同?
- javascript - 我可以在苹果商店没有生产应用程序的情况下测试 react-native-iap 吗?
- typescript - VSCode 中的 Nativescript 共享模式总是用错误“对装饰器的实验支持...”错误为类添加红线
- python - Django Rest Framework - 通过传递 JSON 对象而不仅仅是 ID 来执行 Put 请求
- python - 附加到特定对象的属性,其中对象存储在字典中
- documentum - 删除 DQL 语句中的前 100 个对象
- basic-authentication - Squid 4.5 的基本身份验证 - 未找到 /usr/lib64/squid/basic_ncsa_auth 文件