eddycjy / blog

煎鱼的博客,有点忙,传送门:https://eddycjy.com
3.05k stars 431 forks source link

4.6 Unary and Stream interceptor一节中关于拦截器链的描述有误 #149

Open cuglaiyp opened 3 years ago

cuglaiyp commented 3 years ago

如何实现多个拦截器 另外,可以发现 gRPC 本身居然只能设置一个拦截器,难道所有的逻辑都只能写在一起?

翻看grpc源码可以发现,在调用grpc.NewServer()时候,该函数会用到chainUnaryServerInterceptors函数,这个函数会将ServeroptsunaryInt拦截器和chainUnaryInts拦截器集合,一起打包成一个拦截器链再放回unaryInt字段。 所以grpc原生是支持多拦截器的

chainUnaryServerInterceptors函数源码如下:

func chainUnaryServerInterceptors(s *Server) {
    // Prepend opts.unaryInt to the chaining interceptors if it exists, since unaryInt will
    // be executed before any other chained interceptors.
    interceptors := s.opts.chainUnaryInts
    if s.opts.unaryInt != nil {
        interceptors = append([]UnaryServerInterceptor{s.opts.unaryInt}, s.opts.chainUnaryInts...)
    }

    var chainedInt UnaryServerInterceptor
    if len(interceptors) == 0 {
        chainedInt = nil
    } else if len(interceptors) == 1 {
        chainedInt = interceptors[0]
    } else {
        chainedInt = func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (interface{}, error) {
            return interceptors[0](ctx, req, info, getChainUnaryHandler(interceptors, 0, info, handler))
        }
    }

    s.opts.unaryInt = chainedInt
}