From 62f409810d48bbae9fdd111217e7b2b85d377e60 Mon Sep 17 00:00:00 2001 From: hlx502 <73785906+hlx502@users.noreply.github.com> Date: Wed, 23 Oct 2024 03:17:39 +0800 Subject: [PATCH] netty: Avoid TCP_USER_TIMEOUT warning when not using epoll (#11564) In NettyClientTransport, the TCP_USER_TIMEOUT attribute can be set only if the channel is of the AbstractEpollStreamChannel. Fixes #11517 --- .../io/grpc/netty/NettyClientTransport.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/netty/src/main/java/io/grpc/netty/NettyClientTransport.java b/netty/src/main/java/io/grpc/netty/NettyClientTransport.java index a82470cacb4..426f3c0d583 100644 --- a/netty/src/main/java/io/grpc/netty/NettyClientTransport.java +++ b/netty/src/main/java/io/grpc/netty/NettyClientTransport.java @@ -241,13 +241,6 @@ public Runnable start(Listener transportListener) { b.channelFactory(channelFactory); // For non-socket based channel, the option will be ignored. b.option(SO_KEEPALIVE, true); - // For non-epoll based channel, the option will be ignored. - if (keepAliveTimeNanos != KEEPALIVE_TIME_NANOS_DISABLED) { - ChannelOption tcpUserTimeout = Utils.maybeGetTcpUserTimeoutOption(); - if (tcpUserTimeout != null) { - b.option(tcpUserTimeout, (int) TimeUnit.NANOSECONDS.toMillis(keepAliveTimeoutNanos)); - } - } for (Map.Entry, ?> entry : channelOptions.entrySet()) { // Every entry in the map is obtained from // NettyChannelBuilder#withOption(ChannelOption option, T value) @@ -286,6 +279,20 @@ public void run() { }; } channel = regFuture.channel(); + // For non-epoll based channel, the option will be ignored. + try { + if (keepAliveTimeNanos != KEEPALIVE_TIME_NANOS_DISABLED + && Class.forName("io.netty.channel.epoll.AbstractEpollChannel").isInstance(channel)) { + ChannelOption tcpUserTimeout = Utils.maybeGetTcpUserTimeoutOption(); + if (tcpUserTimeout != null) { + int tcpUserTimeoutMs = (int) TimeUnit.NANOSECONDS.toMillis(keepAliveTimeoutNanos); + channel.config().setOption(tcpUserTimeout, tcpUserTimeoutMs); + } + } + } catch (ClassNotFoundException ignored) { + // JVM did not load AbstractEpollChannel, so the current channel will not be of epoll type, + // so there is no need to set TCP_USER_TIMEOUT + } // Start the write queue as soon as the channel is constructed handler.startWriteQueue(channel); // This write will have no effect, yet it will only complete once the negotiationHandler