aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0279-Async-command-map-building.patch
blob: 370fccd4b4d97c43f235f339b98355c5fc61be65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Callahan <mr.callahhh@gmail.com>
Date: Wed, 8 Apr 2020 02:42:14 -0500
Subject: [PATCH] Async command map building

This adds a custom pool inorder to make sure that they are closed
without much though, as it doesn't matter if the client is not sent
commands if the server is restarting. Using the default async pool caused issues to arise
due to the shutdown logic generally being much later.

diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index eec5279ac4386132fa053c57889e32e6b8141614..b754c0b3e2cd878fca5f702daca64f837ec83451 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -452,6 +452,24 @@ public class Commands {
         if ( org.spigotmc.SpigotConfig.tabComplete < 0 ) return; // Spigot
         // CraftBukkit start
         // Register Vanilla commands into builtRoot as before
+        // Paper start - Perf: Async command map building
+        COMMAND_SENDING_POOL.execute(() -> {
+                this.sendAsync(player);
+        });
+    }
+
+    public static final java.util.concurrent.ThreadPoolExecutor COMMAND_SENDING_POOL = new java.util.concurrent.ThreadPoolExecutor(
+        0, 2, 60L, java.util.concurrent.TimeUnit.SECONDS,
+        new java.util.concurrent.LinkedBlockingQueue<>(),
+        new com.google.common.util.concurrent.ThreadFactoryBuilder()
+            .setNameFormat("Paper Async Command Builder Thread Pool - %1$d")
+            .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(net.minecraft.server.MinecraftServer.LOGGER))
+            .build(),
+        new java.util.concurrent.ThreadPoolExecutor.DiscardPolicy()
+    );
+
+    private void sendAsync(ServerPlayer player) {
+        // Paper end - Perf: Async command map building
         Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues
         RootCommandNode vanillaRoot = new RootCommandNode();
 
@@ -469,7 +487,14 @@ public class Commands {
         for (CommandNode node : rootcommandnode.getChildren()) {
             bukkit.add(node.getName());
         }
+        // Paper start - Perf: Async command map building
+        net.minecraft.server.MinecraftServer.getServer().execute(() -> {
+           runSync(player, bukkit, rootcommandnode);
+        });
+    }
 
+    private void runSync(ServerPlayer player, Collection<String> bukkit, RootCommandNode<SharedSuggestionProvider> rootcommandnode) {
+        // Paper end - Perf: Async command map building
         PlayerCommandSendEvent event = new PlayerCommandSendEvent(player.getBukkitEntity(), new LinkedHashSet<>(bukkit));
         event.getPlayer().getServer().getPluginManager().callEvent(event);
 
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index c543a7e7ef3b26ab610811448b8091894a0a36d5..043dbf59effbbddc5b2e3b8837717997a1771e6f 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -924,6 +924,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
         }
 
         MinecraftServer.LOGGER.info("Stopping server");
+        Commands.COMMAND_SENDING_POOL.shutdownNow(); // Paper - Perf: Async command map building; Shutdown and don't bother finishing
         MinecraftTimings.stopServer(); // Paper
         // CraftBukkit start
         if (this.server != null) {