From 91a872370e85209f977bc896cb1e4c3c3831b2e2 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Thu, 27 Apr 2023 14:18:11 +0200 Subject: [PATCH] Add uncaught exception handlers to executor services --- .../hangar/service/internal/JobService.java | 3 +- .../internal/versions/JarScanningService.java | 4 +-- .../io/papermc/hangar/util/ThreadFactory.java | 34 +++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 backend/src/main/java/io/papermc/hangar/util/ThreadFactory.java diff --git a/backend/src/main/java/io/papermc/hangar/service/internal/JobService.java b/backend/src/main/java/io/papermc/hangar/service/internal/JobService.java index efceec1f..3da5d933 100644 --- a/backend/src/main/java/io/papermc/hangar/service/internal/JobService.java +++ b/backend/src/main/java/io/papermc/hangar/service/internal/JobService.java @@ -6,6 +6,7 @@ import io.papermc.hangar.model.db.JobTable; import io.papermc.hangar.model.internal.job.Job; import io.papermc.hangar.model.internal.job.JobException; import io.papermc.hangar.model.internal.job.SendMailJob; +import io.papermc.hangar.util.ThreadFactory; import jakarta.annotation.PostConstruct; import java.util.List; import java.util.concurrent.ExecutorService; @@ -35,7 +36,7 @@ public class JobService extends HangarComponent { @PostConstruct public void initThreadPool() { - this.executorService = new ThreadPoolExecutor(1, this.config.jobs.maxConcurrentJobs(), 60, TimeUnit.SECONDS, new SynchronousQueue<>()); + this.executorService = new ThreadPoolExecutor(1, this.config.jobs.maxConcurrentJobs(), 60, TimeUnit.SECONDS, new SynchronousQueue<>(), new ThreadFactory("JobService", false)); } public void checkAndProcess() { diff --git a/backend/src/main/java/io/papermc/hangar/service/internal/versions/JarScanningService.java b/backend/src/main/java/io/papermc/hangar/service/internal/versions/JarScanningService.java index 9e616afa..ec8d3a14 100644 --- a/backend/src/main/java/io/papermc/hangar/service/internal/versions/JarScanningService.java +++ b/backend/src/main/java/io/papermc/hangar/service/internal/versions/JarScanningService.java @@ -23,6 +23,7 @@ import io.papermc.hangar.scanner.model.Severity; import io.papermc.hangar.service.internal.file.FileService; import io.papermc.hangar.service.internal.uploads.ProjectFiles; import io.papermc.hangar.service.internal.users.UserService; +import io.papermc.hangar.util.ThreadFactory; import java.io.IOException; import java.io.InputStream; import java.util.Comparator; @@ -40,13 +41,12 @@ import org.springframework.context.event.EventListener; import org.springframework.core.io.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import software.amazon.awssdk.utils.ThreadFactoryBuilder; @Service public class JarScanningService { public static final UUID JAR_SCANNER_USER = new UUID(952332837L, -376012533328L); - private static final ExecutorService EXECUTOR_SERVICE = Executors.newCachedThreadPool(new ThreadFactoryBuilder().threadNamePrefix("Scanner").build()); + private static final ExecutorService EXECUTOR_SERVICE = Executors.newCachedThreadPool(new ThreadFactory("Scanner", true)); private static final Logger LOGGER = LoggerFactory.getLogger(JarScanningService.class); private final HangarJarScanner scanner = new HangarJarScanner(); private final JarScanResultDAO dao; diff --git a/backend/src/main/java/io/papermc/hangar/util/ThreadFactory.java b/backend/src/main/java/io/papermc/hangar/util/ThreadFactory.java new file mode 100644 index 00000000..64e320da --- /dev/null +++ b/backend/src/main/java/io/papermc/hangar/util/ThreadFactory.java @@ -0,0 +1,34 @@ +package io.papermc.hangar.util; + +import io.sentry.Sentry; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import org.jetbrains.annotations.NotNull; + +public class ThreadFactory implements java.util.concurrent.ThreadFactory { + private static final AtomicLong POOL_COUNTER = new AtomicLong(0L); + private final java.util.concurrent.ThreadFactory delegate = Executors.defaultThreadFactory(); + private final AtomicInteger threadCounter = new AtomicInteger(0); + private final boolean daemonThreads; + private final String name; + + public ThreadFactory(final String name, final boolean daemonThreads) { + this.name = name + "-" + POOL_COUNTER.getAndIncrement() % 10_000; + this.daemonThreads = daemonThreads; + } + + @Override + public Thread newThread(final @NotNull Runnable runnable) { + final Thread thread = this.delegate.newThread(runnable); + thread.setName(this.name + "-" + this.threadCounter.getAndIncrement()); + thread.setUncaughtExceptionHandler((t, e) -> { + e.printStackTrace(); + Sentry.captureException(e); + }); + if (this.daemonThreads) { + thread.setDaemon(true); + } + return thread; + } +}