blog icon indicating copy to clipboard operation
blog copied to clipboard

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

Open cuglaiyp opened this issue 3 years ago • 0 comments

如何实现多个拦截器 另外,可以发现 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
}

cuglaiyp avatar Aug 18 '21 09:08 cuglaiyp