From 9d2c3462354734163d540ee947e7c0e3b5b90c12 Mon Sep 17 00:00:00 2001 From: games647 Date: Tue, 22 Feb 2022 16:07:11 +0100 Subject: [PATCH] Use platform scheduler to reuse threads between plugins The platforms usually use a caching thread executor. It makes to use this executor to reuse threads as they are expensive to create. --- .../fastlogin/bukkit/BukkitScheduler.java | 5 +-- .../fastlogin/bukkit/FastLoginBukkit.java | 2 +- .../fastlogin/bungee/FastLoginBungee.java | 2 +- .../fastlogin/core/AsyncScheduler.java | 42 +++++++------------ .../fastlogin/velocity/FastLoginVelocity.java | 2 +- 5 files changed, 21 insertions(+), 32 deletions(-) diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BukkitScheduler.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BukkitScheduler.java index dbffaa1f..f57a71f3 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BukkitScheduler.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/BukkitScheduler.java @@ -28,7 +28,6 @@ package com.github.games647.fastlogin.bukkit; import com.github.games647.fastlogin.core.AsyncScheduler; import java.util.concurrent.Executor; -import java.util.concurrent.ThreadFactory; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; @@ -38,8 +37,8 @@ public class BukkitScheduler extends AsyncScheduler { private final Executor syncExecutor; - public BukkitScheduler(Plugin plugin, Logger logger, ThreadFactory threadFactory) { - super(logger, threadFactory); + public BukkitScheduler(Plugin plugin, Logger logger) { + super(logger, command -> Bukkit.getScheduler().runTaskAsynchronously(plugin, command)); syncExecutor = r -> Bukkit.getScheduler().runTask(plugin, r); } diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java index 7e58b261..a0aeedc5 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java @@ -82,7 +82,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin getProxy().getScheduler().runAsync(this, task)); core = new FastLoginCore<>(this); core.load(); diff --git a/core/src/main/java/com/github/games647/fastlogin/core/AsyncScheduler.java b/core/src/main/java/com/github/games647/fastlogin/core/AsyncScheduler.java index 9086d000..595b1714 100644 --- a/core/src/main/java/com/github/games647/fastlogin/core/AsyncScheduler.java +++ b/core/src/main/java/com/github/games647/fastlogin/core/AsyncScheduler.java @@ -25,14 +25,9 @@ */ package com.github.games647.fastlogin.core; -import com.google.common.util.concurrent.MoreExecutors; - import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicInteger; import org.slf4j.Logger; @@ -53,7 +48,9 @@ public class AsyncScheduler { // 30 threads are still too many - the optimal solution is to separate into processing and blocking threads // where processing threads could only be max number of cores while blocking threads could be minimized using // non-blocking I/O and a single event executor - private final ExecutorService processingPool; + private final Executor processingPool; + + private final AtomicInteger currentlyRunning = new AtomicInteger(); /* private final ExecutorService databaseExecutor = new ThreadPoolExecutor(1, 10, @@ -61,34 +58,27 @@ public class AsyncScheduler { new LinkedBlockingQueue<>(MAX_CAPACITY)); */ - public AsyncScheduler(Logger logger, ThreadFactory threadFactory) { + public AsyncScheduler(Logger logger, Executor processingPool) { this.logger = logger; - processingPool = new ThreadPoolExecutor(6, 32, - 60L, TimeUnit.SECONDS, - new LinkedBlockingQueue<>(MAX_CAPACITY), threadFactory); + this.processingPool = processingPool; } - /* - public CompletableFuture runDatabaseTask(Supplier databaseTask) { - return CompletableFuture.supplyAsync(databaseTask, databaseExecutor) - .exceptionally(error -> { - logger.warn("Error occurred on thread pool", error); - return null; - }) - // change context to the processing pool - .thenApplyAsync(r -> r, processingPool); - } - */ - public CompletableFuture runAsync(Runnable task) { - return CompletableFuture.runAsync(task, processingPool).exceptionally(error -> { + return CompletableFuture.runAsync(() -> { + currentlyRunning.incrementAndGet(); + try { + task.run(); + } finally { + currentlyRunning.getAndDecrement(); + } + }, processingPool).exceptionally(error -> { logger.warn("Error occurred on thread pool", error); return null; }); } public void shutdown() { - MoreExecutors.shutdownAndAwaitTermination(processingPool, 1, TimeUnit.MINUTES); + // MoreExecutors.shutdownAndAwaitTermination(processingPool, 1, TimeUnit.MINUTES); //MoreExecutors.shutdownAndAwaitTermination(databaseExecutor, 1, TimeUnit.MINUTES); } } diff --git a/velocity/src/main/java/com/github/games647/fastlogin/velocity/FastLoginVelocity.java b/velocity/src/main/java/com/github/games647/fastlogin/velocity/FastLoginVelocity.java index d1b581fc..d57e6ad7 100644 --- a/velocity/src/main/java/com/github/games647/fastlogin/velocity/FastLoginVelocity.java +++ b/velocity/src/main/java/com/github/games647/fastlogin/velocity/FastLoginVelocity.java @@ -88,7 +88,7 @@ public class FastLoginVelocity implements PlatformPlugin { @Subscribe public void onProxyInitialization(ProxyInitializeEvent event) { - scheduler = new AsyncScheduler(logger, getThreadFactory()); + scheduler = new AsyncScheduler(logger, task -> server.getScheduler().buildTask(this, task).schedule()); core = new FastLoginCore<>(this); core.load(); loadOrGenerateProxyId();