mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
an absolutely goofy command I'd say (also yet another failsafe, this time for a ton of packet discarding.)
This commit is contained in:
parent
4f06914c39
commit
90cfd37a31
@ -1,7 +1,6 @@
|
||||
package com.hbm.commands;
|
||||
|
||||
import com.hbm.config.GeneralConfig;
|
||||
import com.hbm.handler.radiation.ChunkRadiationManager;
|
||||
import com.hbm.handler.threading.PacketThreading;
|
||||
import com.hbm.util.BobMathUtil;
|
||||
import net.minecraft.command.CommandBase;
|
||||
@ -9,7 +8,9 @@ import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import static com.hbm.handler.threading.PacketThreading.processedCnt;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.ThreadInfo;
|
||||
|
||||
import static com.hbm.handler.threading.PacketThreading.totalCnt;
|
||||
|
||||
public class CommandPacketInfo extends CommandBase {
|
||||
@ -20,59 +21,45 @@ public class CommandPacketInfo extends CommandBase {
|
||||
|
||||
@Override
|
||||
public String getCommandUsage(ICommandSender sender) {
|
||||
return "/ntmpackets <infoall/threadpool/packets>";
|
||||
return "/ntmpackets";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) {
|
||||
if(args.length == 1 && "infoall".equals(args[0])) {
|
||||
sender.addChatMessage(new ChatComponentText("NTM Packet Debugger"));
|
||||
|
||||
if(GeneralConfig.enablePacketThreading)
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "Packet Threading Active"));
|
||||
else
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Packet Threading Inactive"));
|
||||
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Thread Pool Info"));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Thread pool size: " + PacketThreading.threadPool.getPoolSize()));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Thread pool queue: " + PacketThreading.threadPool.getQueue().size()));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Packet Info: " + PacketThreading.threadPool.getPoolSize()));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Amount Processed: " + processedCnt));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Amount Remaining: " + totalCnt));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "% Processed: " + BobMathUtil.roundDecimal(((double) processedCnt / totalCnt) * 100, 2)));
|
||||
return;
|
||||
if(args.length > 0 && args[0].equals("resetState")) {
|
||||
PacketThreading.hasTriggered = false;
|
||||
PacketThreading.clearCnt = 0;
|
||||
}
|
||||
|
||||
if(args.length == 1 && "threadpool".equals(args[0])) {
|
||||
sender.addChatMessage(new ChatComponentText("NTM Packet Debugger"));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GOLD + "NTM Packet Debugger v1.2"));
|
||||
|
||||
if(GeneralConfig.enablePacketThreading)
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "Packet Threading Active"));
|
||||
else
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Packet Threading Inactive"));
|
||||
if(PacketThreading.isTriggered() && GeneralConfig.enablePacketThreading)
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Packet Threading Errored, check log."));
|
||||
else if(GeneralConfig.enablePacketThreading)
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "Packet Threading Active"));
|
||||
else
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Packet Threading Inactive"));
|
||||
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Thread Pool Info"));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Thread pool size: " + PacketThreading.threadPool.getPoolSize()));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Thread pool queue: " + PacketThreading.threadPool.getQueue().size()));
|
||||
return;
|
||||
}
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Thread Pool Info"));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "# Threads (total): " + PacketThreading.threadPool.getPoolSize()));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "# Threads (core): " + PacketThreading.threadPool.getCorePoolSize()));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "# Threads (idle): " + (PacketThreading.threadPool.getPoolSize() - PacketThreading.threadPool.getActiveCount())));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "# Threads (maximum): " + PacketThreading.threadPool.getMaximumPoolSize()));
|
||||
|
||||
if(args.length == 1 && "packets".equals(args[0])) {
|
||||
sender.addChatMessage(new ChatComponentText("NTM Packet Debugger"));
|
||||
for(ThreadInfo thread : ManagementFactory.getThreadMXBean().dumpAllThreads(false, false))
|
||||
if(thread.getThreadName().startsWith("NTM-Packet-Thread-")) {
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GOLD + "Thread Name: " + thread.getThreadName()));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Thread ID: " + thread.getThreadId()));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Thread state: " + thread.getThreadState()));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Locked by: " + (thread.getLockOwnerName() == null ? "None" : thread.getLockName())));
|
||||
}
|
||||
|
||||
if(GeneralConfig.enablePacketThreading)
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "Packet Threading Active"));
|
||||
else
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Packet Threading Inactive"));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GOLD + "Packet Info: "));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Amount total: " + totalCnt));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Amount remaining: " + PacketThreading.threadPool.getQueue().size()));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "% Remaining to process: " + BobMathUtil.roundDecimal(((double) PacketThreading.threadPool.getQueue().size() / totalCnt) * 100, 2) + "%"));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Time spent waiting on thread(s) last tick: " + BobMathUtil.roundDecimal(PacketThreading.nanoTimeWaited / 1000000d, 4) + "ms"));
|
||||
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Packet Info: " + PacketThreading.threadPool.getPoolSize()));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Amount Processed: " + processedCnt));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Amount Remaining: " + totalCnt));
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "% Processed: " + BobMathUtil.roundDecimal(((double) processedCnt / totalCnt) * 100, 2)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + getCommandUsage(sender)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,9 @@ public class GeneralConfig {
|
||||
public static boolean enableThermosPreventer = true;
|
||||
|
||||
public static boolean enablePacketThreading = true;
|
||||
public static int packetThreadingCoreCount = 1;
|
||||
public static int packetThreadingMaxCount = 1;
|
||||
public static boolean packetThreadingErrorBypass = false;
|
||||
|
||||
public static boolean enableDebugMode = true;
|
||||
public static boolean enableMycelium = false;
|
||||
@ -78,6 +81,10 @@ public class GeneralConfig {
|
||||
|
||||
enablePacketThreading = config.get(CATEGORY_GENERAL, "0.01_enablePacketThreading", true, "Enables creation of a separate thread to increase packet processing speed on servers. Disable this if you are having anomalous crashes related to memory connections.").getBoolean(true);
|
||||
|
||||
packetThreadingCoreCount = config.get(CATEGORY_GENERAL, "0.02_packetThreadingCoreCount", 1, "Number of core threads to create for packets (recommended 1).").getInt(1);
|
||||
packetThreadingMaxCount = config.get(CATEGORY_GENERAL, "0.03_packetThreadingMaxCount", 1, "Maximum number of threads to create for packet threading. Must be greater than or equal to 0.02_packetThreadingCoreCount.").getInt(1);
|
||||
packetThreadingErrorBypass = config.get(CATEGORY_GENERAL, "0.04_packetThreadingErrorBypass", false, "Forces the bypassing of most packet threading errors, only enable this if directed to or if you know what you're doing.").getBoolean(false);
|
||||
|
||||
enableDebugMode = config.get(CATEGORY_GENERAL, "1.00_enableDebugMode", false, "Enable debugging mode").getBoolean(false);
|
||||
enableMycelium = config.get(CATEGORY_GENERAL, "1.01_enableMyceliumSpread", false, "Allows glowing mycelium to spread").getBoolean(false);
|
||||
enablePlutoniumOre = config.get(CATEGORY_GENERAL, "1.02_enablePlutoniumNetherOre", false, "Enables plutonium ore generation in the nether").getBoolean(false);
|
||||
|
||||
@ -20,7 +20,7 @@ public class PacketThreading {
|
||||
|
||||
public static int totalCnt = 0;
|
||||
|
||||
public static int processedCnt = 0;
|
||||
public static long nanoTimeWaited = 0;
|
||||
|
||||
public static final List<Future<?>> futureList = new ArrayList<>();
|
||||
|
||||
@ -29,7 +29,26 @@ public class PacketThreading {
|
||||
*/
|
||||
public static void init() {
|
||||
threadPool.setKeepAliveTime(50, TimeUnit.MILLISECONDS);
|
||||
threadPool.allowCoreThreadTimeOut(true);
|
||||
if(GeneralConfig.enablePacketThreading) {
|
||||
if(GeneralConfig.packetThreadingCoreCount < 0 || GeneralConfig.packetThreadingMaxCount <= 0) {
|
||||
MainRegistry.logger.error("0.02_packetThreadingCoreCount < 0 or 0.03_packetThreadingMaxCount is <= 0, defaulting to 1 each.");
|
||||
threadPool.setCorePoolSize(1); // beugh
|
||||
threadPool.setMaximumPoolSize(1);
|
||||
} else if(GeneralConfig.packetThreadingMaxCount > GeneralConfig.packetThreadingCoreCount) {
|
||||
MainRegistry.logger.error("0.03_packetThreadingMaxCount is > 0.02_packetThreadingCoreCount, defaulting to 1 each.");
|
||||
threadPool.setCorePoolSize(1);
|
||||
threadPool.setMaximumPoolSize(1);
|
||||
} else {
|
||||
threadPool.setCorePoolSize(GeneralConfig.packetThreadingCoreCount);
|
||||
threadPool.setMaximumPoolSize(GeneralConfig.packetThreadingMaxCount);
|
||||
}
|
||||
threadPool.allowCoreThreadTimeOut(false);
|
||||
} else {
|
||||
threadPool.allowCoreThreadTimeOut(true);
|
||||
for(Runnable task : threadPool.getQueue()) {
|
||||
task.run(); // Run all tasks async just in-case there *are* tasks left to run.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,10 +68,11 @@ public class PacketThreading {
|
||||
PacketDispatcher.wrapper.sendToAllAround(message, target);
|
||||
if(message instanceof PrecompiledPacket)
|
||||
((PrecompiledPacket) message).getPreBuf().release();
|
||||
processedCnt++;
|
||||
};
|
||||
|
||||
if(GeneralConfig.enablePacketThreading)
|
||||
if(isTriggered())
|
||||
task.run();
|
||||
else if(GeneralConfig.enablePacketThreading)
|
||||
futureList.add(threadPool.submit(task)); // Thread it
|
||||
else
|
||||
task.run(); // no threading :(
|
||||
@ -62,8 +82,9 @@ public class PacketThreading {
|
||||
* Wait until the packet thread is finished processing.
|
||||
*/
|
||||
public static void waitUntilThreadFinished() {
|
||||
long startTime = System.nanoTime();
|
||||
try {
|
||||
if (!(processedCnt >= totalCnt) && !GeneralConfig.enablePacketThreading) {
|
||||
if (GeneralConfig.enablePacketThreading && (!GeneralConfig.packetThreadingErrorBypass && !hasTriggered)) {
|
||||
for (Future<?> future : futureList) {
|
||||
future.get(50, TimeUnit.MILLISECONDS); // I HATE EVERYTHING
|
||||
}
|
||||
@ -71,14 +92,61 @@ public class PacketThreading {
|
||||
} catch (ExecutionException ignored) {
|
||||
// impossible
|
||||
} catch (TimeoutException e) {
|
||||
MainRegistry.logger.warn("A packet has taken >50ms to process, discarding {}/{} packets to prevent pausing of main thread ({} total futures).", totalCnt-processedCnt, totalCnt, futureList.size());
|
||||
threadPool.getQueue().clear();
|
||||
if(!GeneralConfig.packetThreadingErrorBypass && !hasTriggered)
|
||||
MainRegistry.logger.warn("A packet has taken >50ms to process, discarding {}/{} packets to prevent pausing of main thread ({} total futures).", threadPool.getQueue().size(), totalCnt, futureList.size());
|
||||
clearThreadPoolTasks();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt(); // maybe not the best thing but it's gotta be here
|
||||
} finally {
|
||||
futureList.clear();
|
||||
processedCnt = 0;
|
||||
nanoTimeWaited = System.nanoTime() - startTime;
|
||||
if(!threadPool.getQueue().isEmpty()) {
|
||||
if(!GeneralConfig.packetThreadingErrorBypass && !hasTriggered)
|
||||
MainRegistry.logger.warn("Residual packets in packet threading queue detected, discarding {}/{} packets.", threadPool.getQueue().size(), totalCnt);
|
||||
clearThreadPoolTasks(); // Just in case the thread somehow doesn't process all the tasks, we don't want this backing up too far.
|
||||
}
|
||||
|
||||
totalCnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static int clearCnt = 0;
|
||||
|
||||
public static boolean hasTriggered = false;
|
||||
|
||||
public static void clearThreadPoolTasks() {
|
||||
|
||||
if(threadPool.getQueue().isEmpty()) {
|
||||
clearCnt = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
threadPool.getQueue().clear();
|
||||
|
||||
if(!GeneralConfig.packetThreadingErrorBypass && !hasTriggered)
|
||||
MainRegistry.logger.warn("Packet work queue cleared forcefully (clear count: {}).", clearCnt);
|
||||
|
||||
clearCnt++;
|
||||
|
||||
|
||||
if(clearCnt > 5 && !isTriggered()) {
|
||||
// If it's been cleared 5 times in a row, something may have gone really wrong.
|
||||
// Best case scenario here, the server is lagging terribly, has a bad CPU, or has a poor network connection
|
||||
// Worst case scenario, the entire packet thread is dead. (very not good)
|
||||
// So just log it with a special message and only once.
|
||||
MainRegistry.logger.error(
|
||||
"Something has gone wrong and the packet pool has cleared 5 times (or more) in a row. "
|
||||
+ "This can indicate that the thread has been killed, suspended, or is otherwise non-functioning. "
|
||||
+ "This message will only be logged once, further packet operations will continue on the main thread. "
|
||||
+ "If this message is a common occurrence and is *completely expected*, then it can be bypassed permanently by setting "
|
||||
+ "the \"0.04_packetThreadingErrorBypass\" config option to true. This can lead to adverse effects, so do this at your own risk. "
|
||||
+ "Running \"/ntmpacket resetState\" resets this trigger as a temporary fix."
|
||||
);
|
||||
hasTriggered = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isTriggered() {
|
||||
return hasTriggered && !GeneralConfig.packetThreadingErrorBypass;
|
||||
}
|
||||
}
|
||||
|
||||
@ -905,8 +905,6 @@ public class MainRegistry {
|
||||
|
||||
PacketDispatcher.registerPackets();
|
||||
|
||||
PacketThreading.init();
|
||||
|
||||
NeutronHandler neutronHandler = new NeutronHandler();
|
||||
MinecraftForge.EVENT_BUS.register(neutronHandler);
|
||||
FMLCommonHandler.instance().bus().register(neutronHandler);
|
||||
@ -969,6 +967,8 @@ public class MainRegistry {
|
||||
|
||||
config.save();
|
||||
|
||||
PacketThreading.init();
|
||||
|
||||
try {
|
||||
if(GeneralConfig.enableThermosPreventer && Class.forName("thermos.ThermosClassTransformer") != null) {
|
||||
throw new IllegalStateException("The mod tried to start on a Thermos or its fork server and therefore stopped. To allow the server to start on Thermos, change the appropriate "
|
||||
|
||||
@ -84,7 +84,7 @@ public class TileEntityLoadedBase extends TileEntity implements ILoadedTile, IBu
|
||||
return;
|
||||
}
|
||||
|
||||
this.lastPackedBuf = preBuf;
|
||||
this.lastPackedBuf = preBuf.copy();
|
||||
|
||||
PacketThreading.createThreadedPacket(packet, new NetworkRegistry.TargetPoint(this.worldObj.provider.dimensionId, xCoord, yCoord, zCoord, range));
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user