diff --git a/src/main/java/org/cyclops/integratedterminals/IntegratedTerminals.java b/src/main/java/org/cyclops/integratedterminals/IntegratedTerminals.java index 76025573f..1d8fa4625 100644 --- a/src/main/java/org/cyclops/integratedterminals/IntegratedTerminals.java +++ b/src/main/java/org/cyclops/integratedterminals/IntegratedTerminals.java @@ -35,6 +35,7 @@ import org.cyclops.integratedterminals.gametest.GameTestAdvancementsIntegratedTerminals; import org.cyclops.integratedterminals.gametest.GameTestCraftingJobIndication; import org.cyclops.integratedterminals.gametest.GameTestCraftingJobNotify; +import org.cyclops.integratedterminals.gametest.GameTestCraftingPlanWorkerPool; import org.cyclops.integratedterminals.gametest.GameTestIngredientQueryMatchers; import org.cyclops.integratedterminals.gametest.GameTestPendingCraftingJobOutputs; import org.cyclops.integratedterminals.gametest.GameTestTerminalCraftingJobFinishedEvent; @@ -158,6 +159,7 @@ public Class[] getGameTestClasses() { GameTestAdvancementsIntegratedTerminals.class, GameTestCraftingJobIndication.class, GameTestCraftingJobNotify.class, + GameTestCraftingPlanWorkerPool.class, GameTestIngredientQueryMatchers.class, GameTestPendingCraftingJobOutputs.class, GameTestTerminalCraftingJobFinishedEvent.class, diff --git a/src/main/java/org/cyclops/integratedterminals/gametest/GameTestCraftingPlanWorkerPool.java b/src/main/java/org/cyclops/integratedterminals/gametest/GameTestCraftingPlanWorkerPool.java new file mode 100644 index 000000000..c98654d36 --- /dev/null +++ b/src/main/java/org/cyclops/integratedterminals/gametest/GameTestCraftingPlanWorkerPool.java @@ -0,0 +1,23 @@ +package org.cyclops.integratedterminals.gametest; + +import net.minecraft.gametest.framework.GameTestHelper; +import org.cyclops.cyclopscore.gametest.GameTest; +import org.cyclops.integratedterminals.inventory.container.ContainerTerminalStorageCraftingPlanBase; + +import java.util.concurrent.ExecutionException; + +/** + * Game tests for the crafting planner worker pool. + * @author rubensworks + */ +public class GameTestCraftingPlanWorkerPool { + + @GameTest(template = "cyclopscore:empty") + public void testWorkerThreadsAreDaemon(GameTestHelper helper) throws ExecutionException, InterruptedException { + // Non-daemon worker threads would keep the client JVM alive after quitting the game. + boolean daemon = ContainerTerminalStorageCraftingPlanBase.getWorkerPool().submit(() -> Thread.currentThread().isDaemon()).get(); + helper.assertTrue(daemon, "Crafting planner worker threads must be daemon threads"); + helper.succeed(); + } + +} diff --git a/src/main/java/org/cyclops/integratedterminals/inventory/container/ContainerTerminalStorageCraftingPlanBase.java b/src/main/java/org/cyclops/integratedterminals/inventory/container/ContainerTerminalStorageCraftingPlanBase.java index fcb263580..58cabf41d 100644 --- a/src/main/java/org/cyclops/integratedterminals/inventory/container/ContainerTerminalStorageCraftingPlanBase.java +++ b/src/main/java/org/cyclops/integratedterminals/inventory/container/ContainerTerminalStorageCraftingPlanBase.java @@ -1,5 +1,7 @@ package org.cyclops.integratedterminals.inventory.container; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import net.minecraft.core.RegistryAccess; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.SimpleContainer; @@ -29,7 +31,19 @@ public abstract class ContainerTerminalStorageCraftingPlanBase extends InventoryContainer { public static final String BUTTON_START = "start"; - private static final ExecutorService WORKER_POOL = Executors.newFixedThreadPool(GeneralConfig.craftingPlannerThreads); + // Daemon threads, so they don't prevent the client JVM from exiting. + private static final ExecutorService WORKER_POOL = Executors.newFixedThreadPool( + GeneralConfig.craftingPlannerThreads, + new ThreadFactoryBuilder() + .setNameFormat("IntegratedTerminals Crafting Planner #%d") + .setDaemon(true) + .build() + ); + + @VisibleForTesting + public static ExecutorService getWorkerPool() { + return WORKER_POOL; + } private final CraftingOptionGuiData craftingOptionGuiData; private final int craftingPlanNotifierId;