mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-23 00:49:31 +00:00
303 lines
13 KiB
Diff
303 lines
13 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: wangxyper <wangxyper@163.com>
|
|
Date: Wed, 11 Jan 2023 10:10:12 +0800
|
|
Subject: [PATCH] Hearse: Add worker command
|
|
|
|
Original license: MIT
|
|
Original project: https://github.com/NaturalCodeClub/HearseRewrite
|
|
|
|
diff --git a/src/main/java/co/earthme/hearse/Hearse.java b/src/main/java/co/earthme/hearse/Hearse.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..79116449c221e0748e938f40366af03f93a4ab9f
|
|
--- /dev/null
|
|
+++ b/src/main/java/co/earthme/hearse/Hearse.java
|
|
@@ -0,0 +1,25 @@
|
|
+package co.earthme.hearse;
|
|
+
|
|
+import co.earthme.hearse.commands.WorkerCommand;
|
|
+import co.earthme.hearse.server.ServerEntityTickHook;
|
|
+import co.earthme.hearse.workers.WorkerThreadPoolManager;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+
|
|
+public class Hearse {
|
|
+ private static final WorkerThreadPoolManager workerManager = new WorkerThreadPoolManager();
|
|
+
|
|
+ public static void initAll(){
|
|
+ HearseConfig.init();
|
|
+ ServerEntityTickHook.init();
|
|
+ MinecraftServer.getServer().server.getCommandMap().register("workers","hearse",new WorkerCommand());
|
|
+ }
|
|
+
|
|
+ public static void onServerStop(){
|
|
+ HearseConfig.save();
|
|
+ workerManager.shutdownAllNow();
|
|
+ }
|
|
+
|
|
+ public static WorkerThreadPoolManager getWorkerManager() {
|
|
+ return workerManager;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/co/earthme/hearse/commands/WorkerCommand.java b/src/main/java/co/earthme/hearse/commands/WorkerCommand.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..9bf8e0bdfed9a30a302c6369a727e8bb394b4670
|
|
--- /dev/null
|
|
+++ b/src/main/java/co/earthme/hearse/commands/WorkerCommand.java
|
|
@@ -0,0 +1,72 @@
|
|
+package co.earthme.hearse.commands;
|
|
+
|
|
+import co.earthme.hearse.Hearse;
|
|
+import co.earthme.hearse.concurrent.WorkerThreadPoolExecutor;
|
|
+import org.bukkit.ChatColor;
|
|
+import org.bukkit.command.Command;
|
|
+import org.bukkit.command.CommandSender;
|
|
+import org.jetbrains.annotations.NotNull;
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+
|
|
+public class WorkerCommand extends Command {
|
|
+ public WorkerCommand() {
|
|
+ super("workers");
|
|
+ this.setPermission("hearse.commands.workers");
|
|
+ this.setDescription("You can see or edit the server workers by using this command");
|
|
+ this.setUsage("/workers <status,setThreadCount,forceStop> <workername>");
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException {
|
|
+ final List<String> ret = new ArrayList<>();
|
|
+ if (args.length == 1){
|
|
+ ret.add("status");
|
|
+ ret.add("setThreadCount");
|
|
+ ret.add("forceStop");
|
|
+ }
|
|
+ if (args.length == 2){
|
|
+ for (Map.Entry<String, WorkerThreadPoolExecutor> entry : Hearse.getWorkerManager().getManagedWorkers().entrySet()){
|
|
+ ret.add(entry.getKey());
|
|
+ }
|
|
+ }
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
|
|
+ if (args.length >= 2){
|
|
+ final String action = args[0];
|
|
+ final String workerName = args[1];
|
|
+ final WorkerThreadPoolExecutor searchedWorker = Hearse.getWorkerManager().getTargetWorker(workerName);
|
|
+ if (searchedWorker == null){
|
|
+ sender.sendMessage(ChatColor.RED+"Target worker not found!");
|
|
+ return true;
|
|
+ }
|
|
+ switch (action){
|
|
+ case "status":
|
|
+ sender.sendMessage(ChatColor.GREEN+"Worker: "+workerName+" Status:"+ searchedWorker);
|
|
+ break;
|
|
+ case "setThreadCount":
|
|
+ if (args.length == 3){
|
|
+ try {
|
|
+ searchedWorker.setCorePoolSize(Integer.parseInt(args[2]));
|
|
+ sender.sendMessage(ChatColor.GREEN+"Finished!");
|
|
+ }catch (NumberFormatException e){
|
|
+ sender.sendMessage(ChatColor.RED+"Please supply a integer!");
|
|
+ }
|
|
+ }else{
|
|
+ sender.sendMessage(ChatColor.RED+"Please supply a integer!");
|
|
+ }
|
|
+ break;
|
|
+ case "forceStop":
|
|
+ searchedWorker.shutdownNow();
|
|
+ sender.sendMessage(ChatColor.YELLOW+"Worker "+workerName+" has been stopped!");
|
|
+ break;
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java b/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
|
|
index cf7ee6fda90fa0f6827dc2d1c584151e3b99fb38..18c1f6ee4d4fc422fb2aa41483ce145d34fa39b1 100644
|
|
--- a/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
|
|
+++ b/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
|
|
@@ -1,14 +1,13 @@
|
|
package co.earthme.hearse.server;
|
|
|
|
+import co.earthme.hearse.Hearse;
|
|
import co.earthme.hearse.HearseConfig;
|
|
-import co.earthme.hearse.concurrent.WorkerThread;
|
|
import co.earthme.hearse.concurrent.WorkerThreadFactory;
|
|
import co.earthme.hearse.concurrent.WorkerThreadPoolExecutor;
|
|
import co.earthme.hearse.concurrent.threadfactory.DefaultWorkerFactory;
|
|
import net.minecraft.server.MinecraftServer;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.world.entity.Entity;
|
|
-
|
|
import java.util.concurrent.LinkedBlockingQueue;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
@@ -27,14 +26,6 @@ public class ServerEntityTickHook {
|
|
worker.execute(task);
|
|
}
|
|
|
|
- public static void onServerStop() throws InterruptedException {
|
|
- if (!asyncEntityEnabled){
|
|
- return;
|
|
- }
|
|
- worker.shutdown();
|
|
- while (!worker.awaitTermination(100,TimeUnit.MILLISECONDS));
|
|
- }
|
|
-
|
|
public static void init(){
|
|
boolean asyncEntityEnabled1 = HearseConfig.getBoolean("optimizations.enable-async-entity",true);
|
|
final int workerCount = HearseConfig.getInt("workers.async-entity-worker-count",Runtime.getRuntime().availableProcessors());
|
|
@@ -47,6 +38,7 @@ public class ServerEntityTickHook {
|
|
new LinkedBlockingQueue<>(),
|
|
defFactory
|
|
);
|
|
+ Hearse.getWorkerManager().addWorker("entity",worker);
|
|
}
|
|
asyncEntityEnabled = asyncEntityEnabled1;
|
|
}
|
|
diff --git a/src/main/java/co/earthme/hearse/workers/WorkerThreadPoolManager.java b/src/main/java/co/earthme/hearse/workers/WorkerThreadPoolManager.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..90dd97491c0313bee031b81aa43fe6df3dda5b4f
|
|
--- /dev/null
|
|
+++ b/src/main/java/co/earthme/hearse/workers/WorkerThreadPoolManager.java
|
|
@@ -0,0 +1,84 @@
|
|
+package co.earthme.hearse.workers;
|
|
+
|
|
+import co.earthme.hearse.concurrent.WorkerThreadPoolExecutor;
|
|
+import com.google.common.collect.Maps;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.concurrent.TimeUnit;
|
|
+
|
|
+public class WorkerThreadPoolManager {
|
|
+ private final Map<String,WorkerThreadPoolExecutor> managedWorkers = Maps.newConcurrentMap();
|
|
+
|
|
+ public void addWorker(String bound,WorkerThreadPoolExecutor worker){
|
|
+ this.managedWorkers.put(bound,worker);
|
|
+ }
|
|
+
|
|
+ public void shutdownAll() throws InterruptedException {
|
|
+ for (WorkerThreadPoolExecutor worker : this.managedWorkers.values()){
|
|
+ worker.shutdown();
|
|
+ while (worker.awaitTermination(100, TimeUnit.MILLISECONDS)) {}
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public Map<String, WorkerThreadPoolExecutor> getManagedWorkers() {
|
|
+ return Maps.newHashMap(this.managedWorkers);
|
|
+ }
|
|
+
|
|
+ public WorkerThreadPoolExecutor getTargetWorker(String bound){
|
|
+ return this.managedWorkers.get(bound);
|
|
+ }
|
|
+
|
|
+ public Map<String,List<Runnable>> shutdownAllNow(){
|
|
+ final Map<String,List<Runnable>> ret = Maps.newHashMap();
|
|
+ for (Map.Entry<String,WorkerThreadPoolExecutor> entry : this.managedWorkers.entrySet()){
|
|
+ final String workerName = entry.getKey();
|
|
+ final WorkerThreadPoolExecutor worker = entry.getValue();
|
|
+ try {
|
|
+ final List<Runnable> taskNotRunned = worker.shutdownNow();
|
|
+ while (worker.awaitTermination(1,TimeUnit.MILLISECONDS)){
|
|
+
|
|
+ }
|
|
+ ret.put(workerName,taskNotRunned);
|
|
+ }catch (Exception e){
|
|
+ e.printStackTrace();
|
|
+ }
|
|
+ }
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ public Map<String,List<Runnable>> shutdownAllNow(long timeOutCount){
|
|
+ final Map<String,List<Runnable>> ret = Maps.newHashMap();
|
|
+ for (Map.Entry<String,WorkerThreadPoolExecutor> entry : this.managedWorkers.entrySet()){
|
|
+ final String workerName = entry.getKey();
|
|
+ final WorkerThreadPoolExecutor worker = entry.getValue();
|
|
+ try {
|
|
+ long timeCounter = timeOutCount;
|
|
+ final List<Runnable> taskNotRunned = worker.shutdownNow();
|
|
+ while (worker.awaitTermination(1,TimeUnit.MILLISECONDS)){
|
|
+ if (timeCounter == 0){
|
|
+ break;
|
|
+ }
|
|
+ timeCounter--;
|
|
+ }
|
|
+ ret.put(workerName,taskNotRunned);
|
|
+ }catch (Exception e){
|
|
+ e.printStackTrace();
|
|
+ }
|
|
+ }
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ public void shutdownAll(long singleWorkerAwaitTimeOutCount) throws InterruptedException {
|
|
+ long counter = singleWorkerAwaitTimeOutCount;
|
|
+ for (WorkerThreadPoolExecutor worker : this.managedWorkers.values()){
|
|
+ worker.shutdown();
|
|
+ while (worker.awaitTermination(1, TimeUnit.MILLISECONDS)) {
|
|
+ if (counter == 0){
|
|
+ break;
|
|
+ }
|
|
+ counter--;
|
|
+ }
|
|
+ counter = singleWorkerAwaitTimeOutCount;
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
index 9c4811a9936f819e201b93e13519abf10d02ac8e..fe47aff8654283aa6a17a36226aa9fc7f18f9886 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -1,5 +1,6 @@
|
|
package net.minecraft.server;
|
|
|
|
+import co.earthme.hearse.Hearse;
|
|
import co.earthme.hearse.HearseConfig;
|
|
import co.earthme.hearse.server.ServerEntityTickHook;
|
|
import com.google.common.base.Splitter;
|
|
@@ -399,8 +400,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
// Paper end
|
|
Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this));
|
|
this.paperConfigurations = services.paperConfigurations(); // Paper
|
|
- HearseConfig.init();
|
|
- ServerEntityTickHook.init();
|
|
}
|
|
// CraftBukkit end
|
|
|
|
@@ -914,11 +913,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
if (!hasLoggedStop && isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper
|
|
// Paper start - kill main thread, and kill it hard
|
|
HearseConfig.save(); //Hearse
|
|
- try {
|
|
- ServerEntityTickHook.onServerStop(); //Hearse
|
|
- } catch (InterruptedException e) {
|
|
- e.printStackTrace();
|
|
- }
|
|
+ Hearse.onServerStop();//Hearse
|
|
shutdownThread = Thread.currentThread();
|
|
org.spigotmc.WatchdogThread.doStop(); // Paper
|
|
if (!isSameThread()) {
|
|
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
index 1cc5cf3dcf33e89092b2aa689170c775007e4e4a..bfdde51d849b6e94af57bd23c0248ce34f020659 100644
|
|
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
@@ -1,5 +1,6 @@
|
|
package net.minecraft.server.dedicated;
|
|
|
|
+import co.earthme.hearse.Hearse;
|
|
import com.google.common.collect.Lists;
|
|
import com.mojang.authlib.GameProfile;
|
|
import com.mojang.datafixers.DataFixer;
|
|
@@ -225,6 +226,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
|
gg.pufferfish.pufferfish.PufferfishConfig.load(); // Pufferfish
|
|
gg.pufferfish.pufferfish.PufferfishCommand.init(); // Pufferfish
|
|
org.dreeam.leaf.LeafConfig.load(); // Leaf
|
|
+ Hearse.initAll(); //Hearse
|
|
|
|
this.setPvpAllowed(dedicatedserverproperties.pvp);
|
|
this.setFlightAllowed(dedicatedserverproperties.allowFlight);
|