netty: add internal API to fall back to NIO transport (#5611)

This commit is contained in:
Jihun Cho 2019-04-18 13:49:55 -07:00 committed by GitHub
parent 2cdaac2adc
commit dc0171839a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 13 deletions

View File

@ -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();
}

View File

@ -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() {}
}

View File

@ -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<? extends EventLoopGroup> eventLoopGroupPool) {
this.eventLoopGroupPool = checkNotNull(eventLoopGroupPool, "eventLoopGroupPool");
return this;
}

View File

@ -81,7 +81,7 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
SharedResourcePool.forResource(Utils.DEFAULT_WORKER_EVENT_LOOP_GROUP);
private final List<SocketAddress> listenAddresses = new ArrayList<>();
private Class<? extends ServerChannel> channelType = Utils.DEFAULT_SERVER_CHANNEL_TYPE;
private Class<? extends ServerChannel> channelType = null;
private final Map<ChannelOption<?>, Object> channelOptions = new HashMap<>();
private ObjectPool<? extends EventLoopGroup> bossEventLoopGroupPool =
DEFAULT_BOSS_EVENT_LOOP_GROUP_POOL;
@ -193,10 +193,14 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
*/
public NettyServerBuilder bossEventLoopGroup(EventLoopGroup group) {
if (group != null) {
this.bossEventLoopGroupPool = new FixedObjectPool<>(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<? extends EventLoopGroup> bossEventLoopGroupPool) {
this.bossEventLoopGroupPool = checkNotNull(bossEventLoopGroupPool, "bossEventLoopGroupPool");
return this;
}
@ -225,10 +229,15 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
*/
public NettyServerBuilder workerEventLoopGroup(EventLoopGroup group) {
if (group != null) {
this.workerEventLoopGroupPool = new FixedObjectPool<>(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<? extends EventLoopGroup> workerEventLoopGroupPool) {
this.workerEventLoopGroupPool =
checkNotNull(workerEventLoopGroupPool, "workerEventLoopGroupPool");
return this;
}
@ -506,7 +515,7 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
+ "neither should be, otherwise server may not start. Missing values will use Nio "
+ "(NioServerSocketChannel, NioEventLoopGroup) for backward compatibility. "
+ "This will cause an Exception in the future.");
if (channelType == Utils.DEFAULT_SERVER_CHANNEL_TYPE) {
if (channelType == null) {
resolvedChannelType = NioServerSocketChannel.class;
logger.log(Level.FINE, "One or more EventLoopGroup is provided, but Channel type is "
+ "missing. Fall back to NioServerSocketChannel.");
@ -522,6 +531,9 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
+ "BossEventLoopGroup is missing. Fall back to NioEventLoopGroup.");
}
}
if (resolvedChannelType == null) {
resolvedChannelType = Utils.DEFAULT_SERVER_CHANNEL_TYPE;
}
List<NettyServer> transportServers = new ArrayList<>(listenAddresses.size());
for (SocketAddress listenAddress : listenAddresses) {
@ -539,10 +551,10 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
@VisibleForTesting
boolean shouldFallBackToNio() {
boolean hasNonDefault = channelType != Utils.DEFAULT_SERVER_CHANNEL_TYPE
boolean hasNonDefault = channelType != null
|| bossEventLoopGroupPool != DEFAULT_BOSS_EVENT_LOOP_GROUP_POOL
|| workerEventLoopGroupPool != DEFAULT_WORKER_EVENT_LOOP_GROUP_POOL;
boolean hasDefault = channelType == Utils.DEFAULT_SERVER_CHANNEL_TYPE
boolean hasDefault = channelType == null
|| bossEventLoopGroupPool == DEFAULT_BOSS_EVENT_LOOP_GROUP_POOL
|| workerEventLoopGroupPool == DEFAULT_WORKER_EVENT_LOOP_GROUP_POOL;
return hasNonDefault && hasDefault;

View File

@ -248,4 +248,13 @@ public class NettyChannelBuilderTest {
assertFalse(builder.shouldFallBackToNio());
}
@Test
public void useNioTransport_shouldNotFallBack() {
NettyChannelBuilder builder = NettyChannelBuilder.forTarget("fakeTarget");
InternalNettyChannelBuilder.useNioTransport(builder);
assertFalse(builder.shouldFallBackToNio());
}
}

View File

@ -173,4 +173,11 @@ public class NettyServerBuilderTest {
assertFalse(builder.shouldFallBackToNio());
}
@Test
public void useNioTransport_shouldNotFallBack() {
InternalNettyServerBuilder.useNioTransport(builder);
assertFalse(builder.shouldFallBackToNio());
}
}