grpc-spring icon indicating copy to clipboard operation
grpc-spring copied to clipboard

The interceptor is initialized twice

Open s5364733 opened this issue 4 years ago • 5 comments

The interceptor is initialized twice:

Branch : master

Source: local-grpc-client/local-grpc-server

Let's take a look at the picture below:
image

This is what happened when I used the case

My use case:


@GrpcClient(value = "local-grpc-client", interceptors = LogGrpcInterceptor.class )
    private SimpleBlockingStub simpleStub;

The actual effect is as follows:

image

The code show as below:


public class LogGrpcInterceptor implements ClientInterceptor {

    private static final Logger log = LoggerFactory.getLogger(LogGrpcInterceptor.class);

    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method,
            CallOptions callOptions, Channel next) {
        log.info(method.getFullMethodName()+"window");
        return next.newCall(method, callOptions);
    }

}

Suggest:

 @Override
    public Channel createChannel(final String name, final List<ClientInterceptor> customInterceptors,
            final boolean sortInterceptors) {
        final Channel channel;
        synchronized (this) {
            if (this.shutdown) {
                throw new IllegalStateException("GrpcChannelFactory is already closed!");
            }
            channel = this.channels.computeIfAbsent(name, this::newManagedChannel);
        }
        final List<ClientInterceptor> interceptors =
                Lists.newArrayList(this.globalClientInterceptorRegistry.getClientInterceptors());
        interceptors.addAll(customInterceptors);//In fact, there is no need to add once, if you must add, you can use HashSet to remove duplicates
        if (sortInterceptors) {
            this.globalClientInterceptorRegistry.sortInterceptors(interceptors);
        }
        return ClientInterceptors.interceptForward(channel, interceptors);
    }

s5364733 avatar Mar 08 '21 09:03 s5364733

I'm not sure about this one. You (un)intentionally registered the interceptor both globally and specifically, so being executed twice might be correct. What would you expect it to do?

  • Execute twice,
  • Execute once only (the global execution only),
  • Execute once only (the specific execution only),
  • or throw exception?

Please note that this part will change (probably) in the next update to separate the channel creation/management logic from the channel customization (interception) logic.

ST-DDT avatar Mar 10 '21 17:03 ST-DDT

@ST-DDT We are also facing same issue, how can we avoid the interceptor to be registered twice. Is the part of code highlighted in the issue changed in the recent version. Please let me know.

prssnk avatar Oct 17 '22 16:10 prssnk

No, the code hasn't changed for a long time.

Please check where the duplicate comes from. I assume it is (wrongly) registered both globally (GrpcGlobalClientInterceptor) and directly (GrpcClient annotation).

Please also answer to this comment: https://github.com/yidongnan/grpc-spring-boot-starter/issues/505#issuecomment-795778730 ("What would you expect it to do?")

ST-DDT avatar Oct 17 '22 18:10 ST-DDT

Hi @ST-DDT we are creating two server side interceptor both having class level annotations @GrpcGlobalServerInterceptor. We are seeing the both the interceptor are getting called twice.

prssnk avatar Oct 18 '22 07:10 prssnk

Please check whether they are created twice as well (e.g. by adding logs to the constructor or checking the global interceptor registry). If the interceptors aren't created twice, then check the injection itself whether this is from the global interceptor set or a custom interceptor set. https://github.com/yidongnan/grpc-spring-boot-starter/blob/92f8ee68833c0191c5fa4044e2762d6817d1bdea/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/client/channelfactory/AbstractChannelFactory.java#L110

ST-DDT avatar Oct 18 '22 07:10 ST-DDT