Paper/patches/server/0914-Configurable-chat-thread-limit.patch
Spottedleaf 01a13871de
Rewrite chunk system (#8177)
Patch documentation to come

Issues with the old system that are fixed now:
- World generation does not scale with cpu cores effectively.
- Relies on the main thread for scheduling and maintaining chunk state, dropping chunk load/generate rates at lower tps.
- Unreliable prioritisation of chunk gen/load calls that block the main thread.
- Shutdown logic is utterly unreliable, as it has to wait for all chunks to unload - is it guaranteed that the chunk system is in a state on shutdown that it can reliably do this? Watchdog shutdown also typically failed due to thread checks, which is now resolved.
- Saving of data is not unified (i.e can save chunk data without saving entity data, poses problems for desync if shutdown is really abnormal.
- Entities are not loaded with chunks. This caused quite a bit of headache for Chunk#getEntities API, but now the new chunk system loads entities with chunks so that they are ready whenever the chunk loads in. Effectively brings the behavior back to 1.16 era, but still storing entities in their own separate regionfiles.

The above list is not complete. The patch documentation will complete it.

New chunk system hard relies on starlight and dataconverter, and most importantly the new concurrent utilities in ConcurrentUtil.

Some of the old async chunk i/o interface (i.e the old file io thread reroutes _some_ calls to the new file io thread) is kept for plugin compat reasons. It will be removed in the next major version of minecraft.

The old legacy chunk system patches have been moved to the removed folder in case we need them again.
2022-09-26 01:02:51 -07:00

56 lines
3.2 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Sun, 18 Sep 2022 06:33:17 +0100
Subject: [PATCH] Configurable chat thread limit
By default, spigot shifts chat over to an unbounded thread pool,
on a normal server, this really offers no gains, the creation of a thread
on submitting to the pool on these servers eats more time vs just running it in
the netty pipeline, however, on servers using plugins which do work in here, there
could be some overall benefits to moving this stuff outside of the pipeline.
In general, this patch does two things:
1) Exposes the core size for the pool, this allows for ensuring that a number of threads
sit around in the pool, mitigating the need for creating new threads; This IS however
caveated, the ThreadPoolExecutor will ONLY create core threads as they're needed, it
just won't allow for us to dip back under the # of core threads, this can potentially
be mitigated by calling prestartCoreThread, however, I'm not sure if there is much justification
for this
2) Exposes a max size for the pool, as stated, by default this is unbounded, for most
servers limiting the size of the pool is going to have 0 effects given how fast chat
is actually processed, this is honestly really just exposed for the misnomers or people
who just wanna ensure that this won't grow over a specific size if chat gets stupidly active
diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
index 84785fed0d85d78c4caf8fabe35c0e89a59240d5..4a8286c78a9a5e305b19cc5d316bc73a78e49b4d 100644
--- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
@@ -252,13 +252,26 @@ public class GlobalConfiguration extends ConfigurationPart {
public Misc misc;
public class Misc extends ConfigurationPart {
+
+ public ChatThreads chatThreads;
public class ChatThreads extends ConfigurationPart.Post {
private int chatExecutorCoreSize = -1;
private int chatExecutorMaxSize = -1;
@Override
public void postProcess() {
- // TODO: FILL
+ //noinspection ConstantConditions
+ if (net.minecraft.server.MinecraftServer.getServer() == null) return; // In testing env, this will be null here
+ int _chatExecutorMaxSize = (chatExecutorMaxSize <= 0) ? Integer.MAX_VALUE : chatExecutorMaxSize; // This is somewhat dumb, but, this is the default, do we cap this?;
+ int _chatExecutorCoreSize = Math.max(chatExecutorCoreSize, 0);
+
+ if (_chatExecutorMaxSize < _chatExecutorCoreSize) {
+ _chatExecutorMaxSize = _chatExecutorCoreSize;
+ }
+
+ java.util.concurrent.ThreadPoolExecutor executor = (java.util.concurrent.ThreadPoolExecutor) net.minecraft.server.MinecraftServer.getServer().chatExecutor;
+ executor.setCorePoolSize(_chatExecutorCoreSize);
+ executor.setMaximumPoolSize(_chatExecutorMaxSize);
}
}
public int maxJoinsPerTick = 3;