From bb9f3a56001894b991faba542f0a37ce677f8c24 Mon Sep 17 00:00:00 2001 From: Taiyou06 Date: Wed, 26 Mar 2025 18:08:18 +0100 Subject: [PATCH] Optimize NonFlush Packet Sending --- ...0155-Optimize-NonFlush-PacketSending.patch | 55 +++++++++++++++++++ .../network/ConnectionFlushQueueRewrite.java | 30 ---------- .../OptimizeNonFlushPacketSending.java | 35 ++++++++++++ 3 files changed, 90 insertions(+), 30 deletions(-) create mode 100644 leaf-server/minecraft-patches/features/0155-Optimize-NonFlush-PacketSending.patch delete mode 100644 leaf-server/src/main/java/org/dreeam/leaf/config/modules/network/ConnectionFlushQueueRewrite.java create mode 100644 leaf-server/src/main/java/org/dreeam/leaf/config/modules/network/OptimizeNonFlushPacketSending.java diff --git a/leaf-server/minecraft-patches/features/0155-Optimize-NonFlush-PacketSending.patch b/leaf-server/minecraft-patches/features/0155-Optimize-NonFlush-PacketSending.patch new file mode 100644 index 00000000..e1f98674 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0155-Optimize-NonFlush-PacketSending.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Taiyou06 +Date: Wed, 26 Mar 2025 17:33:30 +0100 +Subject: [PATCH] Optimize NonFlush PacketSending + +Places like entity tracking make heavy use of packet sending, +and internally netty will use some very expensive thread wakeup +calls when scheduling. + +Thanks to various hacks in ProtocolLib as well as other +plugins, we cannot simply use a queue of packets to group +send on execute. We have to call execute for each packet. + +Tux's suggestion here is exactly what was needed - tag +the Runnable indicating it should not make a wakeup call. + +Big thanks to Tux for making this possible as I had given +up on this optimisation before he came along. + +Locally this patch drops the entity tracker tick by a full 1.5x. + +Co-authored-by: Quang Tran <3d7777456@gmail.com> + +diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java +index 5b46036868b6c9d082e35591e58735e16adaae62..208674673169b7258d9411d818870a640df08b24 100644 +--- a/net/minecraft/network/Connection.java ++++ b/net/minecraft/network/Connection.java +@@ -147,6 +147,7 @@ public class Connection extends SimpleChannelInboundHandler> { + @Nullable public SocketAddress haProxyAddress; // Paper - Add API to get player's proxy address + // Paper start - Optimize network + public boolean isPending = true; ++ private io.netty.channel.SingleThreadEventLoop eventLoop; // Leaf - optimise packets that are not flushed + public boolean queueImmunity; + // Paper end - Optimize network + +@@ -158,6 +159,7 @@ public class Connection extends SimpleChannelInboundHandler> { + public void channelActive(ChannelHandlerContext context) throws Exception { + super.channelActive(context); + this.channel = context.channel(); ++ this.eventLoop = (io.netty.channel.SingleThreadEventLoop) this.channel.eventLoop(); // Leaf - optimise packets that are not flushed + this.address = this.channel.remoteAddress(); + this.preparing = false; // Spigot + if (this.delayedDisconnect != null) { +@@ -477,6 +479,11 @@ public class Connection extends SimpleChannelInboundHandler> { + if (this.channel.eventLoop().inEventLoop()) { + this.doSendPacket(packet, sendListener, flush); + } else { ++ // Leaf start - optimise packets that are not flushed ++ if (!flush && org.dreeam.leaf.config.modules.network.OptimizeNonFlushPacketSending.enabled) { ++ this.eventLoop.lazyExecute(() -> this.doSendPacket(packet, sendListener, flush)); ++ } else ++ // Leaf end - optimise packets that are not flushed + this.channel.eventLoop().execute(() -> this.doSendPacket(packet, sendListener, flush)); + } + } diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/network/ConnectionFlushQueueRewrite.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/network/ConnectionFlushQueueRewrite.java deleted file mode 100644 index dbeeaa65..00000000 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/network/ConnectionFlushQueueRewrite.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.dreeam.leaf.config.modules.network; - -import org.dreeam.leaf.config.ConfigModules; -import org.dreeam.leaf.config.EnumConfigCategory; - -public class ConnectionFlushQueueRewrite extends ConfigModules { - - public String getBasePath() { - return EnumConfigCategory.NETWORK.getBaseKeyName(); - } - - public static boolean enabled = false; - - @Override - public void onLoaded() { - enabled = config.getBoolean(getBasePath() + ".connection-flush-queue-rewrite", enabled, config.pickStringRegionBased(""" - This replaces ConcurrentLinkedQueue with ArrayDeque for better performance - and uses the Netty event loop to ensure thread safety. - - May increase the Netty thread usage and requires server restart to take effect - Default: false - """, - """ - 此选项将 ConcurrentLinkedQueue 替换为 ArrayDeque 以提高性能, - 并使用 Netty 事件循环以确保线程安全。 - - 默认值: false - """)); - } -} diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/network/OptimizeNonFlushPacketSending.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/network/OptimizeNonFlushPacketSending.java new file mode 100644 index 00000000..5c38c0db --- /dev/null +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/network/OptimizeNonFlushPacketSending.java @@ -0,0 +1,35 @@ +package org.dreeam.leaf.config.modules.network; + +import org.dreeam.leaf.config.ConfigModules; +import org.dreeam.leaf.config.EnumConfigCategory; + +public class OptimizeNonFlushPacketSending extends ConfigModules { + + public String getBasePath() { + return EnumConfigCategory.NETWORK.getBaseKeyName(); + } + + public static boolean enabled = false; + + @Override + public void onLoaded() { + enabled = config.getBoolean(getBasePath() + ".OptimizeNonFlushPacketSending", enabled, config.pickStringRegionBased(""" + WARNING: This option is NOT compatible with ProtocolLib and may cause + issues with other plugins that modify packet handling. + + Optimizes non-flush packet sending by using Netty's lazyExecute method to avoid + expensive thread wakeup calls when scheduling packet operations. + + Requires server restart to take effect. + """, + """ + 警告:此选项与 ProtocolLib 不兼容,并可能导致与其他修改数据包 + 处理的插件出现问题。 + + 通过使用 Netty 的 lazyExecute 方法来优化非刷新数据包的发送, + 避免在调度数据包操作时进行昂贵的线程唤醒调用。 + + 需要重启服务器才能生效。 + """)); + } +}