【问题标题】:How to safely add values to grpc ServerStream in interceptor如何在拦截器中安全地将值添加到 grpc ServerStream
【发布时间】:2020-04-02 00:24:25
【问题描述】:

我的 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),但我没有看到任何类似的东西。我是从错误的角度考虑这个问题,还是我错过了其他东西?

【问题讨论】:

    标签: go grpc grpc-go


    【解决方案1】:

    您需要使用NewIncomingContext 在流中创建当前上下文的副本。

    然后你必须创建一个wrappedStream 类型,它覆盖ServerStream 中的Context 方法以返回修改后的context。您需要将此 wrappedStream 传递给您在拦截器中收到的 handler

    你可以在这里看到一个例子(它覆盖了这里的其他方法,但想法是一样的): https://github.com/grpc/grpc-go/blob/master/examples/features/interceptor/server/main.go#L106-L124

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      Easwar 是对的。

      您可以创建自己的 ServerStream 实现,用您自己的上下文覆盖 Context() 方法,或者 grpc 包内的结构 WrappedServerStream (github.com/grpc-ecosystem/go-grpc-middleware) 您可以传递上下文和原始服务器流对象并在 @ 中使用它987654323@.

      例子:

          // This methods get the current context, and creates a new one
          newContext, err := interceptor.authorize(ss.Context(), info.FullMethod)
          if err != nil {
              log.Printf("authorization failed: %v", err)
              return err
          }
      
          
          err = handler(srv, &grpc_middleware.WrappedServerStream{
              ServerStream:   ss,
              WrappedContext: newContext,
          })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-09
        • 2020-01-21
        • 1970-01-01
        • 2022-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-20
        相关资源
        最近更新 更多