go - 如何在拦截器中安全地将值添加到grpc ServerStream

标签 go grpc grpc-go

我有一个用于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/

相关文章:

docker - 如何在 Pod 间广播 gRPC 流

go - grpc:使用 oneof 会导致无效的内存地址或 nil 指针取消引用

go - 为什么 post 请求在 gin golang 中不起作用?

json - 在golang中解码之前制作一个结构

go - new(T) 和 &T{} 有什么区别?

gRPC 客户端超时

node.js - 如何处理流开始后 grpc-node 中发生的网络错误?

go - protoc-gen-go-rpc : program not found or is not executable - Where do I get protoc-gen-go-rpc?

go - golang中的并发模型grpc服务器

postgresql - sqlx postgres 扫描方法失败