mirror of https://github.com/grpc/grpc-java.git
netty: not using reflection to create NioEventLoopGroup (#5630)
This commit is contained in:
parent
187fe9e146
commit
67ef8c3466
|
@ -16,6 +16,7 @@
|
|||
|
||||
package io.grpc.netty;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static io.grpc.internal.GrpcUtil.CONTENT_TYPE_KEY;
|
||||
import static io.grpc.internal.TransportFrameUtil.toHttp2Headers;
|
||||
import static io.grpc.internal.TransportFrameUtil.toRawSerializedHeaders;
|
||||
|
@ -46,6 +47,7 @@ import io.netty.handler.codec.http2.Http2Headers;
|
|||
import io.netty.util.AsciiString;
|
||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
@ -73,31 +75,35 @@ class Utils {
|
|||
public static final AsciiString TE_TRAILERS = AsciiString.of(GrpcUtil.TE_TRAILERS);
|
||||
public static final AsciiString USER_AGENT = AsciiString.of(GrpcUtil.USER_AGENT_KEY.name());
|
||||
public static final Resource<EventLoopGroup> NIO_BOSS_EVENT_LOOP_GROUP
|
||||
= new DefaultEventLoopGroupResource(1, "grpc-nio-boss-ELG", NioEventLoopGroup.class);
|
||||
= new DefaultEventLoopGroupResource(1, "grpc-nio-boss-ELG", EventLoopGroupType.NIO);
|
||||
public static final Resource<EventLoopGroup> NIO_WORKER_EVENT_LOOP_GROUP
|
||||
= new DefaultEventLoopGroupResource(0, "grpc-nio-worker-ELG", NioEventLoopGroup.class);
|
||||
= new DefaultEventLoopGroupResource(0, "grpc-nio-worker-ELG", EventLoopGroupType.NIO);
|
||||
public static final Resource<EventLoopGroup> DEFAULT_BOSS_EVENT_LOOP_GROUP;
|
||||
public static final Resource<EventLoopGroup> DEFAULT_WORKER_EVENT_LOOP_GROUP;
|
||||
|
||||
public static final Class<? extends ServerChannel> DEFAULT_SERVER_CHANNEL_TYPE;
|
||||
public static final Class<? extends Channel> DEFAULT_CLIENT_CHANNEL_TYPE;
|
||||
|
||||
@Nullable
|
||||
private static final Constructor<? extends EventLoopGroup> EPOLL_EVENT_LOOP_GROUP_CONSTRUCTOR;
|
||||
|
||||
static {
|
||||
// Decide default channel types and EventLoopGroup based on Epoll availability
|
||||
if (isEpollAvailable()) {
|
||||
DEFAULT_SERVER_CHANNEL_TYPE = epollServerChannelType();
|
||||
DEFAULT_CLIENT_CHANNEL_TYPE = epollChannelType();
|
||||
Class<? extends EventLoopGroup> eventLoopGroupType = epollEventLoopGroupType();
|
||||
EPOLL_EVENT_LOOP_GROUP_CONSTRUCTOR = epollEventLoopGroupConstructor();
|
||||
DEFAULT_BOSS_EVENT_LOOP_GROUP
|
||||
= new DefaultEventLoopGroupResource(1, "grpc-default-boss-ELG", eventLoopGroupType);
|
||||
= new DefaultEventLoopGroupResource(1, "grpc-default-boss-ELG", EventLoopGroupType.EPOLL);
|
||||
DEFAULT_WORKER_EVENT_LOOP_GROUP
|
||||
= new DefaultEventLoopGroupResource(0,"grpc-default-worker-ELG", eventLoopGroupType);
|
||||
= new DefaultEventLoopGroupResource(0,"grpc-default-worker-ELG", EventLoopGroupType.EPOLL);
|
||||
} else {
|
||||
logger.log(Level.FINE, "Epoll is not available, using Nio.", getEpollUnavailabilityCause());
|
||||
DEFAULT_SERVER_CHANNEL_TYPE = NioServerSocketChannel.class;
|
||||
DEFAULT_CLIENT_CHANNEL_TYPE = NioSocketChannel.class;
|
||||
DEFAULT_BOSS_EVENT_LOOP_GROUP = NIO_BOSS_EVENT_LOOP_GROUP;
|
||||
DEFAULT_WORKER_EVENT_LOOP_GROUP = NIO_WORKER_EVENT_LOOP_GROUP;
|
||||
EPOLL_EVENT_LOOP_GROUP_CONSTRUCTOR = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,12 +252,15 @@ class Utils {
|
|||
}
|
||||
|
||||
// Must call when epoll is available
|
||||
private static Class<? extends EventLoopGroup> epollEventLoopGroupType() {
|
||||
private static Constructor<? extends EventLoopGroup> epollEventLoopGroupConstructor() {
|
||||
try {
|
||||
return Class
|
||||
.forName("io.netty.channel.epoll.EpollEventLoopGroup").asSubclass(EventLoopGroup.class);
|
||||
.forName("io.netty.channel.epoll.EpollEventLoopGroup").asSubclass(EventLoopGroup.class)
|
||||
.getConstructor(Integer.TYPE, ThreadFactory.class);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException("Cannot load EpollEventLoopGroup", e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException("EpollEventLoopGroup constructor not found", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,16 +277,16 @@ class Utils {
|
|||
}
|
||||
}
|
||||
|
||||
private static EventLoopGroup createEventLoopGroup(
|
||||
Class<? extends EventLoopGroup> eventLoopGroupType,
|
||||
private static EventLoopGroup createEpollEventLoopGroup(
|
||||
int parallelism,
|
||||
ThreadFactory threadFactory) {
|
||||
checkState(EPOLL_EVENT_LOOP_GROUP_CONSTRUCTOR != null, "Epoll is not available");
|
||||
|
||||
try {
|
||||
return eventLoopGroupType
|
||||
.getConstructor(Integer.TYPE, ThreadFactory.class)
|
||||
return EPOLL_EVENT_LOOP_GROUP_CONSTRUCTOR
|
||||
.newInstance(parallelism, threadFactory);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot create EventLoopGroup for " + eventLoopGroupType, e);
|
||||
throw new RuntimeException("Cannot create Epoll EventLoopGroup", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,10 +318,10 @@ class Utils {
|
|||
private static final class DefaultEventLoopGroupResource implements Resource<EventLoopGroup> {
|
||||
private final String name;
|
||||
private final int numEventLoops;
|
||||
private final Class<? extends EventLoopGroup> eventLoopGroupType;
|
||||
private final EventLoopGroupType eventLoopGroupType;
|
||||
|
||||
DefaultEventLoopGroupResource(
|
||||
int numEventLoops, String name, Class<? extends EventLoopGroup> eventLoopGroupType) {
|
||||
int numEventLoops, String name, EventLoopGroupType eventLoopGroupType) {
|
||||
this.name = name;
|
||||
this.numEventLoops = numEventLoops;
|
||||
this.eventLoopGroupType = eventLoopGroupType;
|
||||
|
@ -322,7 +331,14 @@ class Utils {
|
|||
public EventLoopGroup create() {
|
||||
// Use Netty's DefaultThreadFactory in order to get the benefit of FastThreadLocal.
|
||||
ThreadFactory threadFactory = new DefaultThreadFactory(name, /* daemon= */ true);
|
||||
return createEventLoopGroup(eventLoopGroupType, numEventLoops, threadFactory);
|
||||
switch (eventLoopGroupType) {
|
||||
case NIO:
|
||||
return new NioEventLoopGroup(numEventLoops, threadFactory);
|
||||
case EPOLL:
|
||||
return createEpollEventLoopGroup(numEventLoops, threadFactory);
|
||||
default:
|
||||
throw new AssertionError("Unknown/Unsupported EventLoopGroupType: " + eventLoopGroupType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -375,6 +391,11 @@ class Utils {
|
|||
return b.build();
|
||||
}
|
||||
|
||||
private enum EventLoopGroupType {
|
||||
NIO,
|
||||
EPOLL
|
||||
}
|
||||
|
||||
private Utils() {
|
||||
// Prevents instantiation
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue