From ad40d85a05d3d3131ade771d9e574871b8a881d7 Mon Sep 17 00:00:00 2001 From: md_5 Date: Tue, 19 Feb 2013 19:38:18 +1100 Subject: [PATCH] Few fixes, tweaks for Netty --- CraftBukkit-Patches/0025-Netty.patch | 109 +++++++++++++++++++-------- 1 file changed, 77 insertions(+), 32 deletions(-) diff --git a/CraftBukkit-Patches/0025-Netty.patch b/CraftBukkit-Patches/0025-Netty.patch index c5378b0..7fd42ca 100644 --- a/CraftBukkit-Patches/0025-Netty.patch +++ b/CraftBukkit-Patches/0025-Netty.patch @@ -1,23 +1,51 @@ -From 632f1fe0d5566c3eb3df1f3ad1cd0619225e5f5f Mon Sep 17 00:00:00 2001 +From 5469d039435d438a20d93aaa6724f420f6b24f25 Mon Sep 17 00:00:00 2001 From: md_5 Date: Thu, 14 Feb 2013 17:32:20 +1100 -Subject: [PATCH] Netty +Subject: [PATCH] Netty Implement an uber efficient network engine based on the + Java NIO framework Netty. This is basically a complete rewrite of the + Minecraft network engine with many distinct advantages. First and foremost, + there will no longer be the horrid, and redundant case of 2, or even at + times, 3 threads per a connection. Instead low level select/epoll based NIO + is used. The number of threads used for network reading and writing will + scale automatically to the number of cores for use on your server. In most + cases this will be around 8 threads for a 4 core server, much better than the + up to 1000 threads that could be in use at one time with the old engine. To + facilitate asynchronous packet sending or receiving (currently only chat), a + thread pool of 16 threads is kept handy. == Plugin incompatibilities As a + side effect of this change, plugins which rely on very specific + implementation level details within Minecraft are broken. At this point in + time, TagAPI and ProtocolLib are affected. If you are a user of ProtocolLib + you are advised to update to the latest build, where full support is enabled. + If you are a user of TagAPI, support has not yet been added, so you will need + to install the updated ProtocolLib so that TagAPI may use its functions. == + Stability The code within this commit has been very lightly tested in + production (300 players for approximately 24 hours), however it is not + guaranteed to be free from all bugs. If you experence weird connection + behaviour, reporting the bug and steps to reproduce are advised. You are also + free to downgrade to the latest recommend build, which is guaranteed to be + stable. == Summary This commit provides a reduction in threads, which gives + the CPU / operating system more time to allocate to the main server threads, + as well as various other side benefits such as chat thread pooling and a + slight reduction in latency. This commit is licensed under the Creative + Commons Attribution-ShareAlike 3.0 Unported license. --- pom.xml | 5 + - .../java/net/minecraft/server/DedicatedServer.java | 2 +- + .../java/net/minecraft/server/DedicatedServer.java | 4 +- .../net/minecraft/server/Packet51MapChunk.java | 2 +- .../net/minecraft/server/Packet56MapChunkBulk.java | 2 +- .../net/minecraft/server/PendingConnection.java | 13 +- + .../net/minecraft/server/ThreadCommandReader.java | 1 + + .../craftbukkit/scheduler/CraftScheduler.java | 2 +- src/main/java/org/spigotmc/netty/CipherCodec.java | 65 ++++++ - .../org/spigotmc/netty/NettyNetworkManager.java | 228 +++++++++++++++++++ - .../org/spigotmc/netty/NettyServerConnection.java | 105 +++++++++ + .../org/spigotmc/netty/NettyNetworkManager.java | 210 +++++++++++++++++ + .../org/spigotmc/netty/NettyServerConnection.java | 106 +++++++++ .../org/spigotmc/netty/NettySocketAdaptor.java | 248 +++++++++++++++++++++ .../java/org/spigotmc/netty/PacketDecoder.java | 63 ++++++ .../java/org/spigotmc/netty/PacketEncoder.java | 43 ++++ .../java/org/spigotmc/netty/PacketListener.java | 100 +++++++++ src/main/java/org/spigotmc/netty/ReadState.java | 16 ++ - 13 files changed, 885 insertions(+), 7 deletions(-) + 15 files changed, 871 insertions(+), 9 deletions(-) create mode 100644 src/main/java/org/spigotmc/netty/CipherCodec.java create mode 100644 src/main/java/org/spigotmc/netty/NettyNetworkManager.java create mode 100644 src/main/java/org/spigotmc/netty/NettyServerConnection.java @@ -44,9 +72,18 @@ index f17bd19..6b314ec 100644 diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java -index bd0377a..68feb71 100644 +index bd0377a..729177b 100644 --- a/src/main/java/net/minecraft/server/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/DedicatedServer.java +@@ -32,7 +32,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer + public DedicatedServer(joptsimple.OptionSet options) { + super(options); + // CraftBukkit end +- new ThreadSleepForever(this); ++ // new ThreadSleepForever(this); // Spigot + } + + protected boolean init() throws java.net.UnknownHostException { // CraftBukkit - throws UnknownHostException @@ -93,7 +93,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer log.info("Starting Minecraft server on " + (this.getServerIp().length() == 0 ? "*" : this.getServerIp()) + ":" + this.G()); @@ -122,6 +159,31 @@ index 8413a15..70fe839 100644 // CraftBukkit start - fix decompile issues, don't create a list from an array Object[] list = new Object[] { 1, 51, this.server.getVersion(), pingEvent.getMotd(), playerlist.getPlayerCount(), pingEvent.getMaxPlayers() }; +diff --git a/src/main/java/net/minecraft/server/ThreadCommandReader.java b/src/main/java/net/minecraft/server/ThreadCommandReader.java +index 64eaa4c..fbf6fe6 100644 +--- a/src/main/java/net/minecraft/server/ThreadCommandReader.java ++++ b/src/main/java/net/minecraft/server/ThreadCommandReader.java +@@ -11,6 +11,7 @@ class ThreadCommandReader extends Thread { + final DedicatedServer server; + + ThreadCommandReader(DedicatedServer dedicatedserver) { ++ super("Command Reader Thread"); // Spigot + this.server = dedicatedserver; + } + +diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +index 0a5c61a..35badf3 100644 +--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java ++++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +@@ -70,7 +70,7 @@ public class CraftScheduler implements BukkitScheduler { + */ + private final ConcurrentHashMap runners = new ConcurrentHashMap(); + private volatile int currentTick = -1; +- private final Executor executor = Executors.newCachedThreadPool(); ++ private final Executor executor = Executors.newCachedThreadPool(new com.google.common.util.concurrent.ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %1$d").build()); // Spigot + private CraftAsyncDebugger debugHead = new CraftAsyncDebugger(-1, null, null) {@Override StringBuilder debugTo(StringBuilder string) {return string;}}; + private CraftAsyncDebugger debugTail = debugHead; + private static final int RECENT_TICKS; diff --git a/src/main/java/org/spigotmc/netty/CipherCodec.java b/src/main/java/org/spigotmc/netty/CipherCodec.java new file mode 100644 index 0000000..f25af14 @@ -195,12 +257,13 @@ index 0000000..f25af14 +} diff --git a/src/main/java/org/spigotmc/netty/NettyNetworkManager.java b/src/main/java/org/spigotmc/netty/NettyNetworkManager.java new file mode 100644 -index 0000000..adfd877 +index 0000000..0edb062 --- /dev/null +++ b/src/main/java/org/spigotmc/netty/NettyNetworkManager.java -@@ -0,0 +1,228 @@ +@@ -0,0 +1,210 @@ +package org.spigotmc.netty; + ++import com.google.common.util.concurrent.ThreadFactoryBuilder; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundMessageHandlerAdapter; @@ -208,8 +271,6 @@ index 0000000..adfd877 +import java.net.Socket; +import java.net.SocketAddress; +import java.security.PrivateKey; -+import java.util.AbstractList; -+import java.util.List; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; @@ -231,28 +292,12 @@ index 0000000..adfd877 + */ +public class NettyNetworkManager extends ChannelInboundMessageHandlerAdapter implements INetworkManager { + -+ private static final ExecutorService threadPool = Executors.newCachedThreadPool(); ++ private static final ExecutorService threadPool = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("Async Packet Handler - %1$d").build()); + private static final MinecraftServer server = MinecraftServer.getServer(); + private static final PrivateKey key = server.F().getPrivate(); + private static final NettyServerConnection serverConnection = (NettyServerConnection) server.ae(); + /*========================================================================*/ + private final Queue syncPackets = new ConcurrentLinkedQueue(); -+ private final List highPriorityQueue = new AbstractList() { -+ @Override -+ public void add(int index, Packet element) { -+ // NOP -+ } -+ -+ @Override -+ public Packet get(int index) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public int size() { -+ return 0; -+ } -+ }; + private volatile boolean connected; + private Channel channel; + private SocketAddress address; @@ -337,7 +382,6 @@ index 0000000..adfd877 + packet = PacketListener.callQueued(this, connection, packet); + // If handler indicates packet send + if (packet != null) { -+ highPriorityQueue.add(packet); + channel.write(packet); + + // If needed, check and prepare encryption phase @@ -429,12 +473,13 @@ index 0000000..adfd877 +} diff --git a/src/main/java/org/spigotmc/netty/NettyServerConnection.java b/src/main/java/org/spigotmc/netty/NettyServerConnection.java new file mode 100644 -index 0000000..4f08e23 +index 0000000..459919a --- /dev/null +++ b/src/main/java/org/spigotmc/netty/NettyServerConnection.java -@@ -0,0 +1,105 @@ +@@ -0,0 +1,106 @@ +package org.spigotmc.netty; + ++import com.google.common.util.concurrent.ThreadFactoryBuilder; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelException; @@ -488,7 +533,7 @@ index 0000000..4f08e23 + .addLast("encoder", new PacketEncoder()) + .addLast("manager", new NettyNetworkManager()); + } -+ }).group(new NioEventLoopGroup(3)).localAddress(host, port).bind(); ++ }).group(new NioEventLoopGroup(1, new ThreadFactoryBuilder().setNameFormat("Netty IO Thread - %1$d").build())).localAddress(host, port).bind(); + } + + /**