Print server thread stack on async catcher timeout (#910)

This commit is contained in:
IzzelAliz 2023-02-02 13:42:01 +08:00
parent 0bed3a21d4
commit 3eec91d20b
No known key found for this signature in database
GPG Key ID: EE50E123A11D8338
2 changed files with 25 additions and 2 deletions

View File

@ -15,6 +15,7 @@ import net.minecraftforge.server.ServerLifecycleHooks;
import org.bukkit.World;
import org.bukkit.craftbukkit.v.CraftServer;
import org.bukkit.craftbukkit.v.command.ColouredConsoleSender;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.Objects;
@ -23,10 +24,23 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.locks.LockSupport;
import java.util.function.Supplier;
public class ArclightServer {
private static final Executor mainThreadExecutor = ArclightServer::executeOnMainThread;
private interface ExecutorWithThread extends Executor, Supplier<Thread> {}
private static final ExecutorWithThread mainThreadExecutor = new ExecutorWithThread() {
@Override
public void execute(@NotNull Runnable command) {
executeOnMainThread(command);
}
@Override
public Thread get() {
return getMinecraftServer().getRunningThread();
}
};
private static final ExecutorService chatExecutor = Executors.newCachedThreadPool(
new ThreadFactoryBuilder().setDaemon(true).setNameFormat("Async Chat Thread - #%d")
.setThreadFactory(chatFactory()).build());

View File

@ -38,6 +38,7 @@ import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
@ -242,7 +243,15 @@ public class AsyncCatcher implements Implementer {
case BLOCK: {
CallbackInfoReturnable<T> cir = new CallbackInfoReturnable<>(reason, true);
CompletableFuture<T> future = CompletableFuture.supplyAsync(method, executor);
cir.setReturnValue(future.get(5, TimeUnit.SECONDS));
try {
cir.setReturnValue(future.get(5, TimeUnit.SECONDS));
} catch (TimeoutException e) {
var thread = ((Supplier<Thread>) executor).get();
var ex = new Exception("Server thread");
ex.setStackTrace(thread.getStackTrace());
ArclightImplementer.LOGGER.error(MARKER, "Async catcher timeout", ex);
throw e;
}
return cir;
}
case DISPATCH: {