65 lines
4.3 KiB
Diff
65 lines
4.3 KiB
Diff
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||
|
Date: Sun, 8 Aug 2021 16:26:46 -0700
|
||
|
Subject: [PATCH] Do not submit profile lookups to worldgen threads
|
||
|
|
||
|
They block. On network I/O.
|
||
|
|
||
|
If enough tasks are submitted the server will eventually stall
|
||
|
out due to a sync load, as the worldgen threads will be
|
||
|
stalling on profile lookups.
|
||
|
|
||
|
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
|
||
|
index 59437f04911662f06596ef61b91017caa6427eec..69faebb95924946f648cf9f86ff777d3274e3f28 100644
|
||
|
--- a/src/main/java/net/minecraft/Util.java
|
||
|
+++ b/src/main/java/net/minecraft/Util.java
|
||
|
@@ -67,6 +67,22 @@ public class Util {
|
||
|
private static final AtomicInteger WORKER_COUNT = new AtomicInteger(1);
|
||
|
private static final ExecutorService BOOTSTRAP_EXECUTOR = makeExecutor("Bootstrap", -2); // Paper - add -2 priority
|
||
|
private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main", -1); // Paper - add -1 priority
|
||
|
+ // Paper start - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread
|
||
|
+ public static final ExecutorService PROFILE_EXECUTOR = Executors.newFixedThreadPool(2, new java.util.concurrent.ThreadFactory() {
|
||
|
+
|
||
|
+ private final AtomicInteger count = new AtomicInteger();
|
||
|
+
|
||
|
+ @Override
|
||
|
+ public Thread newThread(Runnable run) {
|
||
|
+ Thread ret = new Thread(run);
|
||
|
+ ret.setName("Profile Lookup Executor #" + this.count.getAndIncrement());
|
||
|
+ ret.setUncaughtExceptionHandler((Thread thread, Throwable throwable) -> {
|
||
|
+ LOGGER.fatal("Uncaught exception in thread " + thread.getName(), throwable);
|
||
|
+ });
|
||
|
+ return ret;
|
||
|
+ }
|
||
|
+ });
|
||
|
+ // Paper end - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread
|
||
|
private static final ExecutorService IO_POOL = makeIoExecutor();
|
||
|
public static LongSupplier timeSource = System::nanoTime;
|
||
|
public static final UUID NIL_UUID = new UUID(0L, 0L);
|
||
|
diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||
|
index 66dfa8c844963091b63e1f2f85d0da6dd2cd083c..f5b8ff3032e46173c0e8920efb336b9901331259 100644
|
||
|
--- a/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||
|
+++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||
|
@@ -200,7 +200,7 @@ public class GameProfileCache {
|
||
|
} else {
|
||
|
this.requests.put(username, CompletableFuture.supplyAsync(() -> {
|
||
|
return this.get(username);
|
||
|
- }, Util.backgroundExecutor()).whenCompleteAsync((optional, throwable) -> {
|
||
|
+ }, Util.PROFILE_EXECUTOR).whenCompleteAsync((optional, throwable) -> { // Paper - not a good idea to use BLOCKING OPERATIONS on the worldgen executor
|
||
|
this.requests.remove(username);
|
||
|
}, this.executor).whenCompleteAsync((optional, throwable) -> {
|
||
|
consumer.accept(optional);
|
||
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||
|
index 6381544b0038de9a09c01238638e4e127e4eddc6..f61c313195c3d16d996721b2f8cd0d9a10ce1aaf 100644
|
||
|
--- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||
|
@@ -150,7 +150,7 @@ public class SkullBlockEntity extends BlockEntity {
|
||
|
public static void updateGameprofile(@Nullable GameProfile owner, Consumer<GameProfile> callback) {
|
||
|
if (owner != null && !StringUtil.isNullOrEmpty(owner.getName()) && (!owner.isComplete() || !owner.getProperties().containsKey("textures")) && profileCache != null && sessionService != null) {
|
||
|
profileCache.getAsync(owner.getName(), (profile) -> {
|
||
|
- Util.backgroundExecutor().execute(() -> {
|
||
|
+ Util.PROFILE_EXECUTOR.execute(() -> { // Paper - not a good idea to use BLOCKING OPERATIONS on the worldgen executor
|
||
|
Util.ifElse(profile, (profilex) -> {
|
||
|
Property property = Iterables.getFirst(profilex.getProperties().get("textures"), (Property)null);
|
||
|
if (property == null) {
|