From 9ab385ab7313c763de650ee53996bced4cf4169b Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Mon, 24 Mar 2025 22:52:38 +0300 Subject: [PATCH] include threads by default in spark --- .../features/0001-Rebrand.patch | 12 ++ ...03-Completely-remove-Mojang-profiler.patch | 32 ++-- .../0009-Parallel-world-ticking.patch | 8 +- .../features/0014-Optimize-hoppers.patch | 4 +- .../features/0020-Lag-compensation.patch | 4 +- .../0021-MSPT-Tracking-for-each-world.patch | 4 +- ...uler-s-executeTick-checks-if-there-i.patch | 4 +- .../0034-Catch-update-suppressors.patch | 4 +- .../features/0036-Virtual-Threads.patch | 4 +- .../paper-patches/features/0001-Rebrand.patch | 13 ++ .../features/0002-Configuration.patch | 15 +- .../pathfinding/AsyncPathProcessor.java | 10 +- .../entity/tracking/MultithreadedTracker.java | 11 +- .../ServerLevelTickExecutorThreadFactory.java | 2 + .../divinemc/spark/DivineSparkPlugin.java | 163 +++++++++++++++++- .../divinemc/spark/ThreadDumperRegistry.java | 44 +++++ .../util/NamedAgnosticThreadFactory.java | 2 + 17 files changed, 270 insertions(+), 66 deletions(-) create mode 100644 divinemc-server/src/main/java/org/bxteam/divinemc/spark/ThreadDumperRegistry.java diff --git a/divinemc-server/minecraft-patches/features/0001-Rebrand.patch b/divinemc-server/minecraft-patches/features/0001-Rebrand.patch index e1498e7..1ece2ec 100644 --- a/divinemc-server/minecraft-patches/features/0001-Rebrand.patch +++ b/divinemc-server/minecraft-patches/features/0001-Rebrand.patch @@ -36,6 +36,18 @@ index 1485186d4989874ef89c4e83830f26358a43759c..b48fc9e0b95fe6c8f72c5501b8de374e @SuppressForbidden( reason = "System.out needed before bootstrap" +diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java +index 781030cb2e0316151c20351f04347c8db63f43e1..6bb8afb3b0e92c374474c92fa44dc7b80af0bd73 100644 +--- a/net/minecraft/server/MinecraftServer.java ++++ b/net/minecraft/server/MinecraftServer.java +@@ -1182,6 +1182,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0 && this.tickCount % autosavePeriod == 0; try { this.isSaving = true; -@@ -1607,10 +1573,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop serverPlayer1.connection.suspendFlushing()); this.server.getScheduler().mainThreadHeartbeat(); // CraftBukkit // Paper start - Folia scheduler API -@@ -1725,9 +1683,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Purpur - Ridables @@ -431,7 +431,7 @@ index 781030cb2e0316151c20351f04347c8db63f43e1..c2cc1cd510f501cb8cd7c1c1925cc94a try { serverLevel.tick(hasTimeLeft); } catch (Throwable var7) { -@@ -1782,34 +1733,24 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop serverPlayer1.connection.suspendFlushing()); this.server.getScheduler().mainThreadHeartbeat(); // CraftBukkit -@@ -1713,28 +1738,43 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, ServerLevel> oldLevels = this.levels; Map, ServerLevel> newLevels = Maps.newLinkedHashMap(oldLevels); newLevels.remove(level.dimension()); diff --git a/divinemc-server/minecraft-patches/features/0014-Optimize-hoppers.patch b/divinemc-server/minecraft-patches/features/0014-Optimize-hoppers.patch index b5d445c..e13bcae 100644 --- a/divinemc-server/minecraft-patches/features/0014-Optimize-hoppers.patch +++ b/divinemc-server/minecraft-patches/features/0014-Optimize-hoppers.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Optimize hoppers diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 18c83691fa48abf83ba775d66171d72d9103049c..bc7c8140051192dccdd2500e53d946eb3849b3b8 100644 +index 9f7698f8ce56d5d89cf86f6ea2d5b4d51b18c9a2..351b035d1f3025af28b5147b95b912e0e2ab9212 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -1745,7 +1745,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent serverLevel.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent serverLevel.updateLagCompensationTick(); // Paper - lag compensation diff --git a/divinemc-server/minecraft-patches/features/0020-Lag-compensation.patch b/divinemc-server/minecraft-patches/features/0020-Lag-compensation.patch index 402f7f8..d1f8dc5 100644 --- a/divinemc-server/minecraft-patches/features/0020-Lag-compensation.patch +++ b/divinemc-server/minecraft-patches/features/0020-Lag-compensation.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Lag compensation diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index bc7c8140051192dccdd2500e53d946eb3849b3b8..295eb0f89d18d8ed88b633f2e8257268c07af294 100644 +index 351b035d1f3025af28b5147b95b912e0e2ab9212..1bcccba4df407ec4d53f49c3c2c7493db87b2240 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -289,6 +289,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function threadFunction) { ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system -@@ -1557,6 +1558,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function threadFunction) { ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system -@@ -1705,17 +1706,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop(), new com.google.common.util.concurrent.ThreadFactoryBuilder() diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 4480bb9de51a1a0ffbc1b3c1374876212f1f20db..19ebcc9a175fa1bcd3bb4f954bdda00664a86f19 100644 +index fe2d9328a7e9365f8c7e24e862038bc94ddfe1ca..daf6141a6aed6baf7b8de4030324703a0fe872d3 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -2708,8 +2708,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop(); + this.logger = Logger.getLogger(ID); + this.logger.log(Level.INFO, "This server bundles the spark profiler. For more information please visit https://docs.papermc.io/paper/profiling"); +- this.spark = PaperSparkModule.create(Compatibility.VERSION_1_0, server, this.logger, new PaperScheduler() { ++ this.spark = org.bxteam.divinemc.spark.DivineSparkPlugin.create(Compatibility.VERSION_1_0, server, this.logger, new PaperScheduler() { // DivineMC - use own spark module + @Override + public void executeAsync(final Runnable runnable) { + MCUtil.scheduleAsyncTask(this.catching(runnable, "asynchronous")); diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java index 2e1b7f613de8876095ef39bb0341a3f9520c8d5d..bab0d25e82f85c7b9524ae42e0bb41e6233d71cf 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java diff --git a/divinemc-server/paper-patches/features/0002-Configuration.patch b/divinemc-server/paper-patches/features/0002-Configuration.patch index 1c85f1f..e5221ba 100644 --- a/divinemc-server/paper-patches/features/0002-Configuration.patch +++ b/divinemc-server/paper-patches/features/0002-Configuration.patch @@ -4,21 +4,8 @@ Date: Mon, 27 Jan 2025 20:53:24 +0300 Subject: [PATCH] Configuration -diff --git a/src/main/java/io/papermc/paper/SparksFly.java b/src/main/java/io/papermc/paper/SparksFly.java -index 62e2d5704c348955bc8284dc2d54c933b7bcdd06..341f13e57896f03058ea3ec68e69b7cb946ce3fc 100644 ---- a/src/main/java/io/papermc/paper/SparksFly.java -+++ b/src/main/java/io/papermc/paper/SparksFly.java -@@ -42,7 +42,7 @@ public final class SparksFly { - this.mainThreadTaskQueue = new ConcurrentLinkedQueue<>(); - this.logger = Logger.getLogger(ID); - this.logger.log(Level.INFO, "This server bundles the spark profiler. For more information please visit https://docs.papermc.io/paper/profiling"); -- this.spark = PaperSparkModule.create(Compatibility.VERSION_1_0, server, this.logger, new PaperScheduler() { -+ this.spark = org.bxteam.divinemc.spark.DivineSparkPlugin.create(Compatibility.VERSION_1_0, server, this.logger, new PaperScheduler() { // DivineMC - use own spark module - @Override - public void executeAsync(final Runnable runnable) { - MCUtil.scheduleAsyncTask(this.catching(runnable, "asynchronous")); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index f87062cdaf4e02e51904f275913907c0269f4d41..037ca6ea2edb3c4ff9bf9f7856360cd2c19b7628 100644 +index 362ab47d0cdba42d7174e9558dd9b926538136d1..d0adbe6fc8ed89ece59226905608cdceb04a6752 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1103,6 +1103,13 @@ public final class CraftServer implements Server { diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/entity/pathfinding/AsyncPathProcessor.java b/divinemc-server/src/main/java/org/bxteam/divinemc/entity/pathfinding/AsyncPathProcessor.java index a574e58..5a49663 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/entity/pathfinding/AsyncPathProcessor.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/entity/pathfinding/AsyncPathProcessor.java @@ -1,11 +1,12 @@ package org.bxteam.divinemc.entity.pathfinding; -import com.google.common.util.concurrent.ThreadFactoryBuilder; +import ca.spottedleaf.moonrise.common.util.TickThread; import net.minecraft.server.MinecraftServer; import net.minecraft.world.level.pathfinder.Path; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bxteam.divinemc.DivineConfig; +import org.bxteam.divinemc.util.NamedAgnosticThreadFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,7 +20,7 @@ import java.util.function.Consumer; */ @SuppressWarnings("DuplicatedCode") public class AsyncPathProcessor { - private static final String THREAD_PREFIX = "DivineMC Async Pathfinding"; + private static final String THREAD_PREFIX = "Async Pathfinding"; private static final Logger LOGGER = LogManager.getLogger(THREAD_PREFIX); private static long lastWarnMillis = System.currentTimeMillis(); @@ -28,10 +29,7 @@ public class AsyncPathProcessor { DivineConfig.asyncPathfindingMaxThreads, DivineConfig.asyncPathfindingKeepalive, TimeUnit.SECONDS, getQueueImpl(), - new ThreadFactoryBuilder() - .setNameFormat(THREAD_PREFIX + " Thread - %d") - .setPriority(Thread.NORM_PRIORITY - 2) - .build(), + new NamedAgnosticThreadFactory<>(THREAD_PREFIX, TickThread::new, Thread.NORM_PRIORITY - 2), new RejectedTaskHandler() ); diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/entity/tracking/MultithreadedTracker.java b/divinemc-server/src/main/java/org/bxteam/divinemc/entity/tracking/MultithreadedTracker.java index 483492d..298946c 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/entity/tracking/MultithreadedTracker.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/entity/tracking/MultithreadedTracker.java @@ -2,10 +2,10 @@ package org.bxteam.divinemc.entity.tracking; import ca.spottedleaf.moonrise.common.list.ReferenceList; import ca.spottedleaf.moonrise.common.misc.NearbyPlayers; +import ca.spottedleaf.moonrise.common.util.TickThread; import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup; import ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity; -import com.google.common.util.concurrent.ThreadFactoryBuilder; import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.FullChunkStatus; import net.minecraft.server.level.ServerLevel; @@ -13,6 +13,7 @@ import net.minecraft.world.entity.Entity; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bxteam.divinemc.DivineConfig; +import org.bxteam.divinemc.util.NamedAgnosticThreadFactory; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -26,7 +27,7 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class MultithreadedTracker { - private static final String THREAD_PREFIX = "DivineMC Async Tracker"; + private static final String THREAD_PREFIX = "Async Tracker"; private static final Logger LOGGER = LogManager.getLogger(THREAD_PREFIX); private static long lastWarnMillis = System.currentTimeMillis(); @@ -148,11 +149,7 @@ public class MultithreadedTracker { } private static @NotNull ThreadFactory getThreadFactory() { - return new ThreadFactoryBuilder() - .setThreadFactory(MultithreadedTrackerThread::new) - .setNameFormat(THREAD_PREFIX + " Thread - %d") - .setPriority(Thread.NORM_PRIORITY - 2) - .build(); + return new NamedAgnosticThreadFactory<>(THREAD_PREFIX, TickThread::new, Thread.NORM_PRIORITY - 2); } private static @NotNull RejectedExecutionHandler getRejectedPolicy() { diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/server/ServerLevelTickExecutorThreadFactory.java b/divinemc-server/src/main/java/org/bxteam/divinemc/server/ServerLevelTickExecutorThreadFactory.java index 7f5fc08..5a0eeba 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/server/ServerLevelTickExecutorThreadFactory.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/server/ServerLevelTickExecutorThreadFactory.java @@ -1,6 +1,7 @@ package org.bxteam.divinemc.server; import ca.spottedleaf.moonrise.common.util.TickThread; +import org.bxteam.divinemc.spark.ThreadDumperRegistry; import java.util.concurrent.ThreadFactory; public class ServerLevelTickExecutorThreadFactory implements ThreadFactory { @@ -8,6 +9,7 @@ public class ServerLevelTickExecutorThreadFactory implements ThreadFactory { public ServerLevelTickExecutorThreadFactory(String worldName) { this.worldName = worldName; + ThreadDumperRegistry.REGISTRY.add("serverlevel-tick-worker [" + worldName + "]"); } @Override diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/spark/DivineSparkPlugin.java b/divinemc-server/src/main/java/org/bxteam/divinemc/spark/DivineSparkPlugin.java index 52665a6..acafc87 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/spark/DivineSparkPlugin.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/spark/DivineSparkPlugin.java @@ -1,27 +1,176 @@ package org.bxteam.divinemc.spark; -import me.lucko.spark.paper.PaperSparkPlugin; +import me.lucko.spark.paper.PaperClassSourceLookup; +import me.lucko.spark.paper.PaperCommandSender; +import me.lucko.spark.paper.PaperPlatformInfo; +import me.lucko.spark.paper.PaperPlayerPingProvider; +import me.lucko.spark.paper.PaperTickHook; +import me.lucko.spark.paper.PaperTickReporter; +import me.lucko.spark.paper.PaperWorldInfoProvider; import me.lucko.spark.paper.api.Compatibility; import me.lucko.spark.paper.api.PaperClassLookup; import me.lucko.spark.paper.api.PaperScheduler; +import me.lucko.spark.paper.api.PaperSparkModule; +import me.lucko.spark.paper.common.SparkPlatform; +import me.lucko.spark.paper.common.SparkPlugin; +import me.lucko.spark.paper.common.monitor.ping.PlayerPingProvider; +import me.lucko.spark.paper.common.platform.PlatformInfo; import me.lucko.spark.paper.common.platform.serverconfig.ServerConfigProvider; +import me.lucko.spark.paper.common.platform.world.WorldInfoProvider; +import me.lucko.spark.paper.common.sampler.ThreadDumper; +import me.lucko.spark.paper.common.sampler.source.ClassSourceLookup; +import me.lucko.spark.paper.common.sampler.source.SourceMetadata; +import me.lucko.spark.paper.common.tick.TickHook; +import me.lucko.spark.paper.common.tick.TickReporter; +import me.lucko.spark.paper.common.util.classfinder.ClassFinder; import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Stream; -public class DivineSparkPlugin extends PaperSparkPlugin { - @NotNull - public static DivineSparkPlugin create(Compatibility ignoredCompatibility, Server server, Logger logger, PaperScheduler scheduler, PaperClassLookup classLookup) { +public class DivineSparkPlugin implements PaperSparkModule, SparkPlugin { + private final Server server; + private final Logger logger; + private final PaperScheduler scheduler; + private final PaperClassLookup classLookup; + private final PaperTickHook tickHook; + private final PaperTickReporter tickReporter; + private final ThreadDumper gameThreadDumper; + private final SparkPlatform platform; + + public DivineSparkPlugin(Server server, Logger logger, PaperScheduler scheduler, PaperClassLookup classLookup) { + this.server = server; + this.logger = logger; + this.scheduler = scheduler; + this.classLookup = classLookup; + this.tickHook = new PaperTickHook(); + this.tickReporter = new PaperTickReporter(); + this.gameThreadDumper = new ThreadDumperRegistry(); + this.platform = new SparkPlatform(this); + } + + public static @NotNull PaperSparkModule create(Compatibility compatibility, Server server, Logger logger, PaperScheduler scheduler, PaperClassLookup classLookup) { return new DivineSparkPlugin(server, logger, scheduler, classLookup); } - public DivineSparkPlugin(Server server, Logger logger, PaperScheduler scheduler, PaperClassLookup classLookup) { - super(server, logger, scheduler, classLookup); + public void enable() { + this.platform.enable(); + } + + public void disable() { + this.platform.disable(); + } + + public void executeCommand(CommandSender sender, String[] args) { + this.platform.executeCommand(new PaperCommandSender(sender), args); + } + + public List tabComplete(CommandSender sender, String[] args) { + return this.platform.tabCompleteCommand(new PaperCommandSender(sender), args); + } + + public boolean hasPermission(CommandSender sender) { + return this.platform.hasPermissionForAnyCommand(new PaperCommandSender(sender)); + } + + public Collection getPermissions() { + return this.platform.getAllSparkPermissions(); + } + + public void onServerTickStart() { + this.tickHook.onTick(); + } + + public void onServerTickEnd(double duration) { + this.tickReporter.onTick(duration); + } + + public String getVersion() { + return "1.10.119"; + } + + public Path getPluginDirectory() { + return this.server.getPluginsFolder().toPath().resolve("spark"); + } + + public String getCommandName() { + return "spark"; + } + + public Stream getCommandSenders() { + return Stream.concat(this.server.getOnlinePlayers().stream(), Stream.of(this.server.getConsoleSender())) + .map((x$0) -> new PaperCommandSender(x$0)); + } + + public void executeAsync(Runnable task) { + this.scheduler.executeAsync(task); + } + + public void executeSync(Runnable task) { + this.scheduler.executeSync(task); + } + + public void log(Level level, String msg) { + this.logger.log(level, msg); + } + + public void log(Level level, String msg, Throwable throwable) { + this.logger.log(level, msg, throwable); + } + + public ThreadDumper getDefaultThreadDumper() { + return this.gameThreadDumper; + } + + public TickHook createTickHook() { + return this.tickHook; + } + + public TickReporter createTickReporter() { + return this.tickReporter; + } + + public ClassSourceLookup createClassSourceLookup() { + return new PaperClassSourceLookup(); + } + + public ClassFinder createClassFinder() { + return (className) -> { + try { + return this.classLookup.lookup(className); + } catch (Exception var3) { + return null; + } + }; + } + + public Collection getKnownSources() { + return SourceMetadata.gather(Arrays.asList(this.server.getPluginManager().getPlugins()), Plugin::getName, (plugin) -> plugin.getPluginMeta() + .getVersion(), (plugin) -> String.join(", ", plugin.getPluginMeta() + .getAuthors()), (plugin) -> plugin.getPluginMeta().getDescription()); + } + + public PlayerPingProvider createPlayerPingProvider() { + return new PaperPlayerPingProvider(this.server); } - @Override public ServerConfigProvider createServerConfigProvider() { return new DivineServerConfigProvider(); } + + public WorldInfoProvider createWorldInfoProvider() { + return new PaperWorldInfoProvider(this.server); + } + + public PlatformInfo getPlatformInfo() { + return PaperPlatformInfo.INSTANCE; + } } diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/spark/ThreadDumperRegistry.java b/divinemc-server/src/main/java/org/bxteam/divinemc/spark/ThreadDumperRegistry.java new file mode 100644 index 0000000..25c252b --- /dev/null +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/spark/ThreadDumperRegistry.java @@ -0,0 +1,44 @@ +package org.bxteam.divinemc.spark; + +import me.lucko.spark.paper.common.sampler.ThreadDumper; +import me.lucko.spark.paper.common.util.ThreadFinder; +import me.lucko.spark.paper.proto.SparkSamplerProtos; + +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.util.Objects; +import java.util.concurrent.ConcurrentLinkedQueue; + +public final class ThreadDumperRegistry implements ThreadDumper { + public static final ConcurrentLinkedQueue REGISTRY = new ConcurrentLinkedQueue<>(); + private static final int STACK_TRACE_DEPTH = 10; + private final ThreadFinder threadFinder = new ThreadFinder(); + + @Override + public ThreadInfo[] dumpThreads(final ThreadMXBean threadMXBean) { + return this.threadFinder.getThreads() + .filter(thread -> isThreadIncluded(thread.threadId(), thread.getName())) + .map(thread -> threadMXBean.getThreadInfo(thread.threadId(), STACK_TRACE_DEPTH)) + .filter(Objects::nonNull) + .toArray(ThreadInfo[]::new); + } + + @Override + public boolean isThreadIncluded(long threadId, String threadName) { + for (final String prefix : REGISTRY) { + if (threadName.startsWith(prefix)) { + return true; + } + } + + return false; + } + + @Override + public SparkSamplerProtos.SamplerMetadata.ThreadDumper getMetadata() { + return SparkSamplerProtos.SamplerMetadata.ThreadDumper.newBuilder() + .setType(SparkSamplerProtos.SamplerMetadata.ThreadDumper.Type.SPECIFIC) + .addAllPatterns(REGISTRY) + .build(); + } +} diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/util/NamedAgnosticThreadFactory.java b/divinemc-server/src/main/java/org/bxteam/divinemc/util/NamedAgnosticThreadFactory.java index c0c1293..a3c901c 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/util/NamedAgnosticThreadFactory.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/util/NamedAgnosticThreadFactory.java @@ -3,6 +3,7 @@ package org.bxteam.divinemc.util; import com.mojang.logging.LogUtils; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; +import org.bxteam.divinemc.spark.ThreadDumperRegistry; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; @@ -19,6 +20,7 @@ public class NamedAgnosticThreadFactory implements ThreadFacto this.priority = priority; this.group = Thread.currentThread().getThreadGroup(); this.namePrefix = name + "-"; + ThreadDumperRegistry.REGISTRY.add(namePrefix); } @Override