我有一个用于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
中的ServerStream
方法以返回修改后的context
。您需要将此wrappedStream
传递给在拦截器中收到的handler
。
您可以在此处看到一个示例(它在这里覆盖了其他方法,但是思想是相同的):
https://github.com/grpc/grpc-go/blob/master/examples/features/interceptor/server/main.go#L106-L124
希望这可以帮助。
关于go - 如何在拦截器中安全地将值添加到grpc ServerStream,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60982406/