diff --git a/netty/src/main/java/io/grpc/netty/InternalNettyChannelBuilder.java b/netty/src/main/java/io/grpc/netty/InternalNettyChannelBuilder.java index 3b5348da12..e66f28cac7 100644 --- a/netty/src/main/java/io/grpc/netty/InternalNettyChannelBuilder.java +++ b/netty/src/main/java/io/grpc/netty/InternalNettyChannelBuilder.java @@ -18,6 +18,8 @@ package io.grpc.netty; import io.grpc.Internal; import io.grpc.internal.ClientTransportFactory; +import io.grpc.internal.SharedResourcePool; +import io.netty.channel.socket.nio.NioSocketChannel; /** * Internal {@link NettyChannelBuilder} accessor. This is intended for usage internal to the gRPC @@ -70,6 +72,17 @@ public final class InternalNettyChannelBuilder { builder.setStatsRecordRealTimeMetrics(value); } + /** + * Sets {@link io.grpc.Channel} and {@link io.netty.channel.EventLoopGroup} to Nio. A major + * benefit over using setters is gRPC will manage the life cycle of {@link + * io.netty.channel.EventLoopGroup}. + */ + public static void useNioTransport(NettyChannelBuilder builder) { + builder.channelType(NioSocketChannel.class); + builder + .eventLoopGroupPool(SharedResourcePool.forResource(Utils.NIO_WORKER_EVENT_LOOP_GROUP)); + } + public static ClientTransportFactory buildTransportFactory(NettyChannelBuilder builder) { return builder.buildTransportFactory(); } diff --git a/netty/src/main/java/io/grpc/netty/InternalNettyServerBuilder.java b/netty/src/main/java/io/grpc/netty/InternalNettyServerBuilder.java index 48912f410b..a4e4e103b5 100644 --- a/netty/src/main/java/io/grpc/netty/InternalNettyServerBuilder.java +++ b/netty/src/main/java/io/grpc/netty/InternalNettyServerBuilder.java @@ -17,6 +17,8 @@ package io.grpc.netty; import io.grpc.Internal; +import io.grpc.internal.SharedResourcePool; +import io.netty.channel.socket.nio.NioServerSocketChannel; /** * Internal {@link InternalNettyServerBuilder} accessor. This is intended for usage internal to @@ -41,5 +43,19 @@ public final class InternalNettyServerBuilder { builder.setTracingEnabled(value); } + /** + * Sets {@link io.grpc.Channel} and {@link io.netty.channel.EventLoopGroup}s to Nio. A major + * benefit over using existing setters is gRPC will manage the life cycle of {@link + * io.netty.channel.EventLoopGroup}s. + */ + public static void useNioTransport(NettyServerBuilder builder) { + builder.channelType(NioServerSocketChannel.class); + builder + .bossEventLoopGroupPool(SharedResourcePool.forResource(Utils.NIO_BOSS_EVENT_LOOP_GROUP)); + builder + .workerEventLoopGroupPool( + SharedResourcePool.forResource(Utils.NIO_WORKER_EVENT_LOOP_GROUP)); + } + private InternalNettyServerBuilder() {} } diff --git a/netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java b/netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java index a1cd1105d7..2b94cb4493 100644 --- a/netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java +++ b/netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java @@ -218,10 +218,13 @@ public final class NettyChannelBuilder */ public NettyChannelBuilder eventLoopGroup(@Nullable EventLoopGroup eventLoopGroup) { if (eventLoopGroup != null) { - this.eventLoopGroupPool = new FixedObjectPool<>(eventLoopGroup); - } else { - this.eventLoopGroupPool = DEFAULT_EVENT_LOOP_GROUP_POOL; + return eventLoopGroupPool(new FixedObjectPool<>(eventLoopGroup)); } + return eventLoopGroupPool(DEFAULT_EVENT_LOOP_GROUP_POOL); + } + + NettyChannelBuilder eventLoopGroupPool(ObjectPool eventLoopGroupPool) { + this.eventLoopGroupPool = checkNotNull(eventLoopGroupPool, "eventLoopGroupPool"); return this; } diff --git a/netty/src/main/java/io/grpc/netty/NettyServerBuilder.java b/netty/src/main/java/io/grpc/netty/NettyServerBuilder.java index b946622be4..2e30b05dfa 100644 --- a/netty/src/main/java/io/grpc/netty/NettyServerBuilder.java +++ b/netty/src/main/java/io/grpc/netty/NettyServerBuilder.java @@ -81,7 +81,7 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder listenAddresses = new ArrayList<>(); - private Class channelType = Utils.DEFAULT_SERVER_CHANNEL_TYPE; + private Class channelType = null; private final Map, Object> channelOptions = new HashMap<>(); private ObjectPool bossEventLoopGroupPool = DEFAULT_BOSS_EVENT_LOOP_GROUP_POOL; @@ -193,10 +193,14 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder(group); - } else { - this.bossEventLoopGroupPool = DEFAULT_BOSS_EVENT_LOOP_GROUP_POOL; + return bossEventLoopGroupPool(new FixedObjectPool<>(group)); } + return bossEventLoopGroupPool(DEFAULT_BOSS_EVENT_LOOP_GROUP_POOL); + } + + NettyServerBuilder bossEventLoopGroupPool( + ObjectPool bossEventLoopGroupPool) { + this.bossEventLoopGroupPool = checkNotNull(bossEventLoopGroupPool, "bossEventLoopGroupPool"); return this; } @@ -225,10 +229,15 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder(group); - } else { - this.workerEventLoopGroupPool = DEFAULT_WORKER_EVENT_LOOP_GROUP_POOL; + return workerEventLoopGroupPool(new FixedObjectPool<>(group)); } + return workerEventLoopGroupPool(DEFAULT_WORKER_EVENT_LOOP_GROUP_POOL); + } + + NettyServerBuilder workerEventLoopGroupPool( + ObjectPool workerEventLoopGroupPool) { + this.workerEventLoopGroupPool = + checkNotNull(workerEventLoopGroupPool, "workerEventLoopGroupPool"); return this; } @@ -506,7 +515,7 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder transportServers = new ArrayList<>(listenAddresses.size()); for (SocketAddress listenAddress : listenAddresses) { @@ -539,10 +551,10 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder