From ae5cd82c1254d1859a3dc3f96a380bbe239eaa63 Mon Sep 17 00:00:00 2001 From: Taiyou06 Date: Wed, 5 Mar 2025 15:37:38 +0100 Subject: [PATCH] add a toggle --- ...write-queue-on-Connection.flushQueue.patch | 102 +++++++++++++----- ...-t-block-main-thread-in-Connection-.patch} | 2 +- .../network/ConnectionFlushQueueRewrite.java | 30 ++++++ 3 files changed, 105 insertions(+), 29 deletions(-) rename leaf-server/minecraft-patches/features/{0125-ShreddedPaper-Don-t-block-main-thread-in-Connection-.patch => 0126-ShreddedPaper-Don-t-block-main-thread-in-Connection-.patch} (91%) create mode 100644 leaf-server/src/main/java/org/dreeam/leaf/config/modules/network/ConnectionFlushQueueRewrite.java diff --git a/leaf-server/minecraft-patches/features/0125-Rewrite-queue-on-Connection.flushQueue.patch b/leaf-server/minecraft-patches/features/0125-Rewrite-queue-on-Connection.flushQueue.patch index 4390b4f0..eed84175 100644 --- a/leaf-server/minecraft-patches/features/0125-Rewrite-queue-on-Connection.flushQueue.patch +++ b/leaf-server/minecraft-patches/features/0125-Rewrite-queue-on-Connection.flushQueue.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Rewrite queue on Connection.flushQueue diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java -index 7b78c0af4a83bd39a5bc2d6554cc677bd4c0c822..5498a5bc1e4af413569a9f3b280c561884c66718 100644 +index 7b78c0af4a83bd39a5bc2d6554cc677bd4c0c822..570a6b844319491b1e07df0a3e55d0b29533c649 100644 --- a/net/minecraft/network/Connection.java +++ b/net/minecraft/network/Connection.java @@ -85,7 +85,7 @@ public class Connection extends SimpleChannelInboundHandler> { @@ -13,27 +13,32 @@ index 7b78c0af4a83bd39a5bc2d6554cc677bd4c0c822..5498a5bc1e4af413569a9f3b280c5618 private final PacketFlow receiving; private volatile boolean sendLoginDisconnect = true; - private final Queue pendingActions = Queues.newConcurrentLinkedQueue(); // Paper - Optimize network -+ private final Queue pendingActions = new java.util.ArrayDeque<>(); // Paper - Optimize network // Leaf - Rewrite queue on Connection.flushQueue ++ private final Queue pendingActions = org.dreeam.leaf.config.modules.network.ConnectionFlushQueueRewrite.enabled ? new java.util.ArrayDeque<>() : Queues.newConcurrentLinkedQueue(); // Paper - Optimize network // Leaf - Rewrite queue on Connection.flushQueue public Channel channel; public SocketAddress address; // Spigot start -@@ -541,10 +541,11 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -541,9 +541,17 @@ public class Connection extends SimpleChannelInboundHandler> { if (io.papermc.paper.util.MCUtil.isMainThread()) { return this.processQueue(); } else if (this.isPending) { - // Should only happen during login/status stages - synchronized (this.pendingActions) { - return this.processQueue(); -- } -+ // Leaf start - Rewrite queue on Connection.flushQueue -+ // Submit to the event loop to ensure thread confinement -+ this.channel.eventLoop().execute(this::processQueue); -+ return false; -+ // Leaf end - Rewrite queue on Connection.flushQueue ++ if (org.dreeam.leaf.config.modules.network.ConnectionFlushQueueRewrite.enabled) { ++ // Leaf start - Rewrite queue on Connection.flushQueue ++ // Submit to the event loop to ensure thread confinement ++ this.channel.eventLoop().execute(this::processQueue); ++ return false; ++ // Leaf end - Rewrite queue on Connection.flushQueue ++ } else { ++ // Original Paper behavior ++ synchronized (this.pendingActions) { ++ return this.processQueue(); ++ } + } } return false; - } -@@ -554,29 +555,19 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -554,36 +562,56 @@ public class Connection extends SimpleChannelInboundHandler> { return true; } @@ -42,30 +47,71 @@ index 7b78c0af4a83bd39a5bc2d6554cc677bd4c0c822..5498a5bc1e4af413569a9f3b280c5618 - final java.util.Iterator iterator = this.pendingActions.iterator(); - while (iterator.hasNext()) { - final WrappedConsumer queued = iterator.next(); // poll -> peek -- ++ if (org.dreeam.leaf.config.modules.network.ConnectionFlushQueueRewrite.enabled) { ++ // Leaf start - Rewrite queue on Connection.flushQueue ++ WrappedConsumer queued; ++ while ((queued = this.pendingActions.poll()) != null) { ++ if (queued instanceof PacketSendAction packetSendAction) { ++ final Packet packet = packetSendAction.packet; ++ if (!packet.isReady()) { ++ // Re-add to the front and exit ++ this.pendingActions.add(queued); ++ return false; ++ } ++ } + - // Fix NPE (Spigot bug caused by handleDisconnection()) - if (queued == null) { - return true; -- } -- ++ if (queued.tryMarkConsumed()) { ++ queued.accept(this); ++ } + } ++ // Leaf end - Rewrite queue on Connection.flushQueue ++ } else { ++ // If we are on main, we are safe here in that nothing else should be processing queue off main anymore ++ // But if we are not on main due to login/status, the parent is synchronized on packetQueue ++ final java.util.Iterator iterator = this.pendingActions.iterator(); ++ while (iterator.hasNext()) { ++ final WrappedConsumer queued = iterator.next(); // poll -> peek ++ ++ // Fix NPE (Spigot bug caused by handleDisconnection()) ++ if (queued == null) { ++ return true; ++ } + - if (queued.isConsumed()) { - continue; - } -- -+ // Leaf start - Rewrite queue on Connection.flushQueue -+ WrappedConsumer queued; -+ while ((queued = this.pendingActions.poll()) != null) { - if (queued instanceof PacketSendAction packetSendAction) { - final Packet packet = packetSendAction.packet; - if (!packet.isReady()) { -+ // Re-add to the front and exit -+ this.pendingActions.add(queued); - return false; ++ if (queued.isConsumed()) { ++ continue; ++ } + +- if (queued instanceof PacketSendAction packetSendAction) { +- final Packet packet = packetSendAction.packet; +- if (!packet.isReady()) { +- return false; ++ if (queued instanceof PacketSendAction packetSendAction) { ++ final Packet packet = packetSendAction.packet; ++ if (!packet.isReady()) { ++ return false; ++ } } - } +- } - iterator.remove(); -+ // Leaf end - Rewrite queue on Connection.flushQueue - if (queued.tryMarkConsumed()) { - queued.accept(this); +- if (queued.tryMarkConsumed()) { +- queued.accept(this); ++ iterator.remove(); ++ if (queued.tryMarkConsumed()) { ++ queued.accept(this); ++ } } + } + return true; + } +- // Paper end - Optimize network ++// Paper end - Optimize network + + private static final int MAX_PER_TICK = io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxJoinsPerTick; // Paper - Buffer joins to world + private static int joinAttemptsThisTick; // Paper - Buffer joins to world diff --git a/leaf-server/minecraft-patches/features/0125-ShreddedPaper-Don-t-block-main-thread-in-Connection-.patch b/leaf-server/minecraft-patches/features/0126-ShreddedPaper-Don-t-block-main-thread-in-Connection-.patch similarity index 91% rename from leaf-server/minecraft-patches/features/0125-ShreddedPaper-Don-t-block-main-thread-in-Connection-.patch rename to leaf-server/minecraft-patches/features/0126-ShreddedPaper-Don-t-block-main-thread-in-Connection-.patch index 4dbf348a..7fdc13ad 100644 --- a/leaf-server/minecraft-patches/features/0125-ShreddedPaper-Don-t-block-main-thread-in-Connection-.patch +++ b/leaf-server/minecraft-patches/features/0126-ShreddedPaper-Don-t-block-main-thread-in-Connection-.patch @@ -6,7 +6,7 @@ Subject: [PATCH] ShreddedPaper: Don't block main thread in diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java -index 7b78c0af4a83bd39a5bc2d6554cc677bd4c0c822..66cc43aec8ddc7b4f1fb3655a7a119d003681b8b 100644 +index 570a6b844319491b1e07df0a3e55d0b29533c649..5a8133497d9c1260a3bba7e9dc7f3b059bbe6b1a 100644 --- a/net/minecraft/network/Connection.java +++ b/net/minecraft/network/Connection.java @@ -325,6 +325,7 @@ public class Connection extends SimpleChannelInboundHandler> { 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 new file mode 100644 index 00000000..d3b8fc44 --- /dev/null +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/network/ConnectionFlushQueueRewrite.java @@ -0,0 +1,30 @@ +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 + """)); + } +}