geforkt von Mirrors/Velocity
Add kqueue transport support
Dieser Commit ist enthalten in:
Ursprung
512b1c2403
Commit
db8b7c807c
@ -28,6 +28,7 @@ dependencies {
|
|||||||
compile "io.netty:netty-handler:${nettyVersion}"
|
compile "io.netty:netty-handler:${nettyVersion}"
|
||||||
compile "io.netty:netty-transport-native-epoll:${nettyVersion}"
|
compile "io.netty:netty-transport-native-epoll:${nettyVersion}"
|
||||||
compile "io.netty:netty-transport-native-epoll:${nettyVersion}:linux-x86_64"
|
compile "io.netty:netty-transport-native-epoll:${nettyVersion}:linux-x86_64"
|
||||||
|
compile "io.netty:netty-transport-native-kqueue:${nettyVersion}:osx-x86_64"
|
||||||
|
|
||||||
compile "org.apache.logging.log4j:log4j-api:${log4jVersion}"
|
compile "org.apache.logging.log4j:log4j-api:${log4jVersion}"
|
||||||
compile "org.apache.logging.log4j:log4j-core:${log4jVersion}"
|
compile "org.apache.logging.log4j:log4j-core:${log4jVersion}"
|
||||||
|
@ -24,6 +24,7 @@ import io.netty.channel.epoll.EpollDatagramChannel;
|
|||||||
import io.netty.channel.epoll.EpollEventLoopGroup;
|
import io.netty.channel.epoll.EpollEventLoopGroup;
|
||||||
import io.netty.channel.epoll.EpollServerSocketChannel;
|
import io.netty.channel.epoll.EpollServerSocketChannel;
|
||||||
import io.netty.channel.epoll.EpollSocketChannel;
|
import io.netty.channel.epoll.EpollSocketChannel;
|
||||||
|
import io.netty.channel.kqueue.*;
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import io.netty.channel.socket.DatagramChannel;
|
import io.netty.channel.socket.DatagramChannel;
|
||||||
import io.netty.channel.socket.ServerSocketChannel;
|
import io.netty.channel.socket.ServerSocketChannel;
|
||||||
@ -37,6 +38,7 @@ import org.apache.logging.log4j.Logger;
|
|||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -53,46 +55,25 @@ import static com.velocitypowered.network.Connections.READ_TIMEOUT;
|
|||||||
public final class ConnectionManager {
|
public final class ConnectionManager {
|
||||||
private static final Logger logger = LogManager.getLogger(ConnectionManager.class);
|
private static final Logger logger = LogManager.getLogger(ConnectionManager.class);
|
||||||
|
|
||||||
private static final String DISABLE_EPOLL_PROPERTY = "velocity.connection.disable-epoll";
|
|
||||||
private static final boolean DISABLE_EPOLL = Boolean.getBoolean(DISABLE_EPOLL_PROPERTY);
|
|
||||||
private final Set<Channel> endpoints = new HashSet<>();
|
private final Set<Channel> endpoints = new HashSet<>();
|
||||||
private final Class<? extends ServerSocketChannel> serverSocketChannelClass;
|
private final TransportType transportType;
|
||||||
private final Class<? extends SocketChannel> socketChannelClass;
|
|
||||||
private final Class<? extends DatagramChannel> datagramChannelClass;
|
|
||||||
private final EventLoopGroup bossGroup;
|
private final EventLoopGroup bossGroup;
|
||||||
private final EventLoopGroup workerGroup;
|
private final EventLoopGroup workerGroup;
|
||||||
|
|
||||||
public ConnectionManager() {
|
public ConnectionManager() {
|
||||||
final boolean epoll = canUseEpoll();
|
this.transportType = TransportType.bestType();
|
||||||
if (epoll) {
|
this.bossGroup = transportType.createEventLoopGroup(true);
|
||||||
this.serverSocketChannelClass = EpollServerSocketChannel.class;
|
this.workerGroup = transportType.createEventLoopGroup(false);
|
||||||
this.socketChannelClass = EpollSocketChannel.class;
|
this.logChannelInformation();
|
||||||
this.datagramChannelClass = EpollDatagramChannel.class;
|
|
||||||
this.bossGroup = new EpollEventLoopGroup(0, createThreadFactory("Netty Epoll Boss #%d"));
|
|
||||||
this.workerGroup = new EpollEventLoopGroup(0, createThreadFactory("Netty Epoll Worker #%d"));
|
|
||||||
} else {
|
|
||||||
this.serverSocketChannelClass = NioServerSocketChannel.class;
|
|
||||||
this.socketChannelClass = NioSocketChannel.class;
|
|
||||||
this.datagramChannelClass = NioDatagramChannel.class;
|
|
||||||
this.bossGroup = new NioEventLoopGroup(0, createThreadFactory("Netty Nio Boss #%d"));
|
|
||||||
this.workerGroup = new NioEventLoopGroup(0, createThreadFactory("Netty Nio Worker #%d"));
|
|
||||||
}
|
|
||||||
this.logChannelInformation(epoll);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logChannelInformation(final boolean epoll) {
|
private void logChannelInformation() {
|
||||||
final StringBuilder sb = new StringBuilder();
|
logger.info("Using channel type {}", transportType);
|
||||||
sb.append("Using channel type ");
|
|
||||||
sb.append(epoll ? "epoll": "nio");
|
|
||||||
if(DISABLE_EPOLL) {
|
|
||||||
sb.append(String.format(" - epoll explicitly disabled using -D%s=true", DISABLE_EPOLL_PROPERTY));
|
|
||||||
}
|
|
||||||
logger.info(sb.toString()); // TODO: move to logger
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(final InetSocketAddress address) {
|
public void bind(final InetSocketAddress address) {
|
||||||
final ServerBootstrap bootstrap = new ServerBootstrap()
|
final ServerBootstrap bootstrap = new ServerBootstrap()
|
||||||
.channel(this.serverSocketChannelClass)
|
.channel(this.transportType.serverSocketChannelClass)
|
||||||
.group(this.bossGroup, this.workerGroup)
|
.group(this.bossGroup, this.workerGroup)
|
||||||
.childHandler(new ChannelInitializer<Channel>() {
|
.childHandler(new ChannelInitializer<Channel>() {
|
||||||
@Override
|
@Override
|
||||||
@ -129,7 +110,7 @@ public final class ConnectionManager {
|
|||||||
|
|
||||||
public void queryBind(final String hostname, final int port) {
|
public void queryBind(final String hostname, final int port) {
|
||||||
Bootstrap bootstrap = new Bootstrap()
|
Bootstrap bootstrap = new Bootstrap()
|
||||||
.channel(datagramChannelClass)
|
.channel(transportType.datagramChannelClass)
|
||||||
.group(this.workerGroup)
|
.group(this.workerGroup)
|
||||||
.handler(new GS4QueryHandler())
|
.handler(new GS4QueryHandler())
|
||||||
.localAddress(hostname, port);
|
.localAddress(hostname, port);
|
||||||
@ -147,7 +128,7 @@ public final class ConnectionManager {
|
|||||||
|
|
||||||
public Bootstrap createWorker() {
|
public Bootstrap createWorker() {
|
||||||
return new Bootstrap()
|
return new Bootstrap()
|
||||||
.channel(this.socketChannelClass)
|
.channel(this.transportType.socketChannelClass)
|
||||||
.group(this.workerGroup);
|
.group(this.workerGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,14 +143,61 @@ public final class ConnectionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean canUseEpoll() {
|
|
||||||
return Epoll.isAvailable() && !DISABLE_EPOLL;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ThreadFactory createThreadFactory(final String nameFormat) {
|
private static ThreadFactory createThreadFactory(final String nameFormat) {
|
||||||
return new ThreadFactoryBuilder()
|
return new ThreadFactoryBuilder()
|
||||||
.setNameFormat(nameFormat)
|
.setNameFormat(nameFormat)
|
||||||
.setDaemon(true)
|
.setDaemon(true)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum TransportType {
|
||||||
|
NIO(NioServerSocketChannel.class, NioSocketChannel.class, NioDatagramChannel.class) {
|
||||||
|
@Override
|
||||||
|
public EventLoopGroup createEventLoopGroup(boolean boss) {
|
||||||
|
String name = "Netty NIO " + (boss ? "Boss" : "Worker") + " #%d";
|
||||||
|
return new NioEventLoopGroup(0, createThreadFactory(name));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
EPOLL(EpollServerSocketChannel.class, EpollSocketChannel.class, EpollDatagramChannel.class) {
|
||||||
|
@Override
|
||||||
|
public EventLoopGroup createEventLoopGroup(boolean boss) {
|
||||||
|
String name = "Netty Epoll " + (boss ? "Boss" : "Worker") + " #%d";
|
||||||
|
return new EpollEventLoopGroup(0, createThreadFactory(name));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
KQUEUE(KQueueServerSocketChannel.class, KQueueSocketChannel.class, KQueueDatagramChannel.class) {
|
||||||
|
@Override
|
||||||
|
public EventLoopGroup createEventLoopGroup(boolean boss) {
|
||||||
|
String name = "Netty Kqueue " + (boss ? "Boss" : "Worker") + " #%d";
|
||||||
|
return new KQueueEventLoopGroup(0, createThreadFactory(name));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final Class<? extends ServerSocketChannel> serverSocketChannelClass;
|
||||||
|
private final Class<? extends SocketChannel> socketChannelClass;
|
||||||
|
private final Class<? extends DatagramChannel> datagramChannelClass;
|
||||||
|
|
||||||
|
TransportType(Class<? extends ServerSocketChannel> serverSocketChannelClass, Class<? extends SocketChannel> socketChannelClass, Class<? extends DatagramChannel> datagramChannelClass) {
|
||||||
|
this.serverSocketChannelClass = serverSocketChannelClass;
|
||||||
|
this.socketChannelClass = socketChannelClass;
|
||||||
|
this.datagramChannelClass = datagramChannelClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name().toLowerCase(Locale.US);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract EventLoopGroup createEventLoopGroup(boolean boss);
|
||||||
|
|
||||||
|
public static TransportType bestType() {
|
||||||
|
if (Epoll.isAvailable()) {
|
||||||
|
return EPOLL;
|
||||||
|
} else if (KQueue.isAvailable()) {
|
||||||
|
return KQUEUE;
|
||||||
|
} else {
|
||||||
|
return NIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren