grpc-ecosystem / grpc-spring

Spring Boot starter module for gRPC framework.
https://grpc-ecosystem.github.io/grpc-spring/
Apache License 2.0
3.51k stars 823 forks source link

GrpcServerConfigurer not configuring threads as expected #593

Open javierseixas opened 2 years ago

javierseixas commented 2 years ago

The context

I'm trying to understand how grpc server is handling thread creation and usage, so I can control it manually.

The question

I'm running a grpc server in my local, in which I'm customizing the threading forcing to have just 1 thread, like this:

  @Bean
  public GrpcServerConfigurer customServer() {
    ExecutorService executor = Executors.newFixedThreadPool(1);

    return serverBuilder -> {
      if (serverBuilder instanceof NettyServerBuilder) {
        System.out.println("Configured server executor!!!");
        ((NettyServerBuilder) serverBuilder)
                .executor(executor)
                .workerEventLoopGroup(new NioEventLoopGroup(1))
                .bossEventLoopGroup(new NioEventLoopGroup(1))
                .channelType(NioServerSocketChannel.class)
                .permitKeepAliveWithoutCalls(true);
      }
    };
  }

When I process several requests, I would expect to receive and process them all one by one, but I see how the grpc server process all them in parallel, so It seems I'm not configuring well the server.

The application's environment

Which versions do you use?

ST-DDT commented 2 years ago

I'm trying to understand how grpc server is handling thread creation and usage, so I can control it manually.

For these intricacies, it is best to ask these questions directly at grpc-java as they know far more than we do. We only over a wrapper/integration for spring boot and some configuration options.

I'm running a grpc server in my local, in which I'm customizing the threading forcing to have just 1 thread, like this:

Is the code block executed? This library default to the shaded Netty server which is a slightly different import than the normal Netty server (builder).

If yes, then I assume that you run into the issue of context switches.

A single grpc call isn't always executed by a single thread, but only one thread at a time AFAIK. I observed thread switches after the start of request/for each sent message within a call and before completing the request. Thats why you cannot use ThreadLocals there blindly. Please note that there are slight differences between unary and streaming calls.

When I process several requests, I would expect to receive and process them all one by one, but I see how the grpc server process all them in parallel, so It seems I'm not configuring well the server.

Streaming or unary calls? Do you execute multiple requests at once/simultaniously or multiple requests interweavingly/alternatingly. You can test that by blocking inside your code.