zalopay-oss/jmeter-grpc-plugin

Keep alive configuration

megasolis opened this issue · 3 comments

Hello, first of all, thanks for this amazing plugin. I have been using it for about 3 months now and it rocks!

Having said that, I have a question regarding how I can configure the time out values of the GRPC ManagedChannel used to send the GRPC requests.

  • One of my use cases is to send some large requests to a GRPC service that may take more than 60 seconds to complete.
  • At first, I thought on just configuring the timeout parameter of the client sampler with a proper value ~120K milliseconds
  • Nevertheless, even with that configuration in place, those big requests get cancelled at around 60 seconds of start with the following Exception: Caused by: io.grpc.StatusRuntimeException: UNAVAILABLE: Network closed for unknown reason
  • After doing some troubleshooting, I wrote a simple GRPC Kotlin client to try to send those same requests. The basic configuration of the ManagedChannel is as follows:
channel = NettyChannelBuilder.forAddress(SERVICE_HOST, SERVICE_PORT)
            .useTransportSecurity()
            .sslContext(
                GrpcSslContexts.forClient().trustManager(File(CERT_PATH)).build()
            )
            .keepAliveWithoutCalls(true)
            .keepAliveTime(30, TimeUnit.SECONDS)
            .keepAliveTimeout(30, TimeUnit.SECONDS)
            .build()
        determinationAPIBlockingStub = DeterminationAPIGrpc.newBlockingStub(channel)
  • As you can see, I specified keepAliveWithoutCalls as true, keepAliveTime with 30 seconds and keepAliveTimeout with 30 seconds as well
  • Previous configuration allowed the channel to be "idle" for more than 60 seconds, therefore, succeeding the request call, so I think this might be the issue of the connection being closed
  • Exploring the GrpcClientSampler.java class, I noticed that there is no way of specifying keep alive values when creating the channel
public static ManagedChannel getChannel(GrpcClientSampler sampler) throws SSLException {
    Map<String, String> headerMap = createHeaderMap(sampler.getMetaData());

    ManagedChannelBuilder builder = NettyChannelBuilder.forAddress(sampler.getHostname(), sampler.getPort())
        .intercept(new GrpcClientInterceptor(headerMap, sampler.getTimeout()));

    if (!sampler.isUseSsl()) {
      builder = builder.usePlaintext();
    } else if (!StringUtils.isBlank(sampler.getCertFile())) {
      // build out a managed channel that can accept the ssl cert file
      // Get the file and verify it exists
      File certFile = new File(sampler.getCertFile());
      if (!certFile.exists()) {
        LOGGER.error("The cert file passed in does not exist at: ", sampler.getCertFile());
      }

      // build the client side ssl context with the cert
      SslContext sslContext = GrpcSslContexts.forClient().trustManager(certFile).build();

      // add the ssl context to the builder
      builder = ((NettyChannelBuilder) builder).sslContext(sslContext);
    }
    return builder.build();
  }

So, I was wondering if there is a workaround or some recommended approach on how to configure the sampler channel to use specific keep alive configuration values.

Thanks in advance.

Screen Shot 2021-08-25 at 00 16 47

Workaround solution is fork this repo, change those lines of code, and rebuild the plugin :v

Created a PR where I have included new code for this and other configuration properties: #21

Thanks

Do small things with great love!

Merged! Thank you!