From 8f90fea16ef6209022f88fbb93f3f35c4c0ba85b Mon Sep 17 00:00:00 2001 From: Vankka Date: Fri, 21 Jun 2024 17:55:01 +0300 Subject: [PATCH] Scheduler convenience methods, scheduler stuff cleanup --- .../bukkit/scheduler/IBukkitScheduler.java | 11 +++ .../bukkit/scheduler/IFoliaScheduler.java | 7 +- .../BukkitGameCommandExecutionHelper.java | 35 +++------- .../integration/EssentialsXIntegration.java | 2 +- .../bukkit/integration/VaultIntegration.java | 13 +--- .../bukkit/player/BukkitPlayerProvider.java | 4 +- .../bukkit/scheduler/BukkitScheduler.java | 7 +- .../bukkit/scheduler/FoliaScheduler.java | 7 +- .../discordsrv/common/AbstractDiscordSRV.java | 2 +- .../discordsrv/common/ServerDiscordSRV.java | 4 +- .../connection/jda/JDAConnectionManager.java | 8 +-- .../common/function/CheckedRunnable.java | 4 +- .../future/util/CompletableFutureUtil.java | 38 +++++++--- .../discordsrv/common/http/util/HttpUtil.java | 8 +-- .../impl/MinecraftAuthenticationLinker.java | 10 +-- .../common/linking/impl/StorageLinker.java | 69 +++++++------------ .../requirement/MinecraftAuthRequirement.java | 21 ++---- .../game/JoinMessageModule.java | 31 +++------ .../common/scheduler/Scheduler.java | 32 +++++++-- .../common/scheduler/ServerScheduler.java | 35 ++++++++-- .../common/scheduler/StandardScheduler.java | 6 +- 21 files changed, 178 insertions(+), 176 deletions(-) diff --git a/bukkit/folia/src/main/java/com/discordsrv/bukkit/scheduler/IBukkitScheduler.java b/bukkit/folia/src/main/java/com/discordsrv/bukkit/scheduler/IBukkitScheduler.java index 4e2b4ebf..10a0a244 100644 --- a/bukkit/folia/src/main/java/com/discordsrv/bukkit/scheduler/IBukkitScheduler.java +++ b/bukkit/folia/src/main/java/com/discordsrv/bukkit/scheduler/IBukkitScheduler.java @@ -18,11 +18,14 @@ package com.discordsrv.bukkit.scheduler; +import com.discordsrv.common.function.CheckedSupplier; +import com.discordsrv.common.future.util.CompletableFutureUtil; import com.discordsrv.common.scheduler.ServerScheduler; import org.bukkit.Server; import org.bukkit.command.CommandSender; import org.bukkit.plugin.Plugin; +import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; public interface IBukkitScheduler extends ServerScheduler { @@ -33,4 +36,12 @@ public interface IBukkitScheduler extends ServerScheduler { runOnMainThread(task); } + default CompletableFuture executeOnMainThread(CommandSender sender, Runnable runnable) { + return CompletableFuture.runAsync(runnable, task -> runOnMainThread(sender, task)); + } + + default CompletableFuture supplyOnMainThread(CommandSender sender, CheckedSupplier supplier) { + return CompletableFutureUtil.supplyAsync(supplier, task -> runOnMainThread(sender, task)); + } + } diff --git a/bukkit/folia/src/main/java/com/discordsrv/bukkit/scheduler/IFoliaScheduler.java b/bukkit/folia/src/main/java/com/discordsrv/bukkit/scheduler/IFoliaScheduler.java index 41fa4d2c..24fe2b78 100644 --- a/bukkit/folia/src/main/java/com/discordsrv/bukkit/scheduler/IFoliaScheduler.java +++ b/bukkit/folia/src/main/java/com/discordsrv/bukkit/scheduler/IFoliaScheduler.java @@ -23,6 +23,7 @@ import org.bukkit.command.BlockCommandSender; import org.bukkit.command.CommandSender; import org.bukkit.command.ProxiedCommandSender; import org.bukkit.entity.Entity; +import org.jetbrains.annotations.NotNull; public interface IFoliaScheduler extends ServerScheduler, IBukkitScheduler { @@ -51,17 +52,17 @@ public interface IFoliaScheduler extends ServerScheduler, IBukkitScheduler { } @Override - default void runOnMainThread(Runnable task) { + default void runOnMainThread(@NotNull Runnable task) { runWithArgs((server, plugin) -> server.getGlobalRegionScheduler().execute(plugin, task)); } @Override - default void runOnMainThreadLaterInTicks(Runnable task, int ticks) { + default void runOnMainThreadLaterInTicks(@NotNull Runnable task, int ticks) { runWithArgs((server, plugin) -> server.getGlobalRegionScheduler().runDelayed(plugin, r -> task.run(), ticks)); } @Override - default void runOnMainThreadAtFixedRateInTicks(Runnable task, int initialTicks, int rateTicks) { + default void runOnMainThreadAtFixedRateInTicks(@NotNull Runnable task, int initialTicks, int rateTicks) { runWithArgs((server, plugin) -> server.getGlobalRegionScheduler().execute(plugin, task)); } } diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/command/game/BukkitGameCommandExecutionHelper.java b/bukkit/src/main/java/com/discordsrv/bukkit/command/game/BukkitGameCommandExecutionHelper.java index da3d4a10..d39acdbb 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/command/game/BukkitGameCommandExecutionHelper.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/command/game/BukkitGameCommandExecutionHelper.java @@ -35,20 +35,14 @@ public class BukkitGameCommandExecutionHelper implements GameCommandExecutionHel if (PaperCommandMap.IS_AVAILABLE) { // If Paper's CommandMap is available we can list out 'root' commands - CompletableFuture> future = new CompletableFuture<>(); - discordSRV.scheduler().runOnMainThread(discordSRV.server().getConsoleSender(), () -> { - try { - for (String cmd : PaperCommandMap.getKnownCommands(discordSRV.server())) { - if (commandName == null || cmd.startsWith(commandName)) { - suggestions.add(cmd); - } + return discordSRV.scheduler().supplyOnMainThread(discordSRV.server().getConsoleSender(), () -> { + for (String cmd : PaperCommandMap.getKnownCommands(discordSRV.server())) { + if (commandName == null || cmd.startsWith(commandName)) { + suggestions.add(cmd); } - future.complete(suggestions); - } catch (Throwable t) { - future.completeExceptionally(t); } + return suggestions; }); - return future; } return CompletableFuture.completedFuture(suggestions); @@ -57,24 +51,17 @@ public class BukkitGameCommandExecutionHelper implements GameCommandExecutionHel // Get the arguments minus the last one (if any) String prefix = parts.isEmpty() ? "" : String.join(" ", parts.subList(0, parts.size() - 1)) + " "; - CompletableFuture> future = new CompletableFuture<>(); CommandSender commandSender = discordSRV.server().getConsoleSender(); - discordSRV.scheduler().runOnMainThread(commandSender, () -> { - try { - List completions = command.tabComplete(commandSender, commandName, parts.toArray(new String[0])); + return discordSRV.scheduler().supplyOnMainThread(commandSender, () -> { + List completions = command.tabComplete(commandSender, commandName, parts.toArray(new String[0])); - List suggestions = new ArrayList<>(); - for (String suggestion : completions) { - suggestions.add(commandName + " " + prefix + suggestion); - } - future.complete(suggestions); - } catch (Throwable t) { - future.completeExceptionally(t); + List suggestions = new ArrayList<>(); + for (String suggestion : completions) { + suggestions.add(commandName + " " + prefix + suggestion); } + return suggestions; }); - - return future; } @Override diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/integration/EssentialsXIntegration.java b/bukkit/src/main/java/com/discordsrv/bukkit/integration/EssentialsXIntegration.java index 2cff2542..355a8bc6 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/integration/EssentialsXIntegration.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/integration/EssentialsXIntegration.java @@ -70,7 +70,7 @@ public class EssentialsXIntegration } private CompletableFuture getUser(UUID playerUUID) { - return CompletableFuture.supplyAsync(() -> get().getUsers().loadUncachedUser(playerUUID), discordSRV.scheduler().executor()); + return discordSRV.scheduler().supply(() -> get().getUsers().loadUncachedUser(playerUUID)); } @Override diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/integration/VaultIntegration.java b/bukkit/src/main/java/com/discordsrv/bukkit/integration/VaultIntegration.java index e0b63a49..3abfa439 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/integration/VaultIntegration.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/integration/VaultIntegration.java @@ -116,20 +116,11 @@ public class VaultIntegration extends PluginIntegration implem } private CompletableFuture supply(CheckedSupplier supplier, boolean async) { - CompletableFuture future = new CompletableFuture<>(); - Runnable runnable = () -> { - try { - future.complete(supplier.get()); - } catch (Throwable e) { - future.completeExceptionally(e); - } - }; if (async) { - discordSRV.scheduler().run(runnable); + return discordSRV.scheduler().supply(supplier); } else { - discordSRV.scheduler().runOnMainThread(runnable); + return discordSRV.scheduler().supplyOnMainThread(supplier); } - return future; } private OfflinePlayer offlinePlayer(UUID player) { diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/player/BukkitPlayerProvider.java b/bukkit/src/main/java/com/discordsrv/bukkit/player/BukkitPlayerProvider.java index 82bbe6af..844e6a10 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/player/BukkitPlayerProvider.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/player/BukkitPlayerProvider.java @@ -77,14 +77,14 @@ public class BukkitPlayerProvider extends ServerPlayerProvider getFuture(Supplier provider) { - return CompletableFuture.supplyAsync(() -> { + return discordSRV.scheduler().supply(() -> { OfflinePlayer offlinePlayer = provider.get(); if (offlinePlayer == null) { return null; } return new BukkitOfflinePlayer(discordSRV, offlinePlayer); - }, discordSRV.scheduler().executor()); + }); } @Override diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/scheduler/BukkitScheduler.java b/bukkit/src/main/java/com/discordsrv/bukkit/scheduler/BukkitScheduler.java index f543a1b2..df124521 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/scheduler/BukkitScheduler.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/scheduler/BukkitScheduler.java @@ -19,6 +19,7 @@ package com.discordsrv.bukkit.scheduler; import com.discordsrv.bukkit.BukkitDiscordSRV; +import org.jetbrains.annotations.NotNull; public class BukkitScheduler extends AbstractBukkitScheduler { @@ -27,17 +28,17 @@ public class BukkitScheduler extends AbstractBukkitScheduler { } @Override - public void runOnMainThread(Runnable task) { + public void runOnMainThread(@NotNull Runnable task) { checkDisable(task, (server, plugin) -> server.getScheduler().runTask(plugin, task)); } @Override - public void runOnMainThreadLaterInTicks(Runnable task, int ticks) { + public void runOnMainThreadLaterInTicks(@NotNull Runnable task, int ticks) { checkDisable(task, (server, plugin) -> server.getScheduler().runTaskLater(plugin, task, ticks)); } @Override - public void runOnMainThreadAtFixedRateInTicks(Runnable task, int initialTicks, int rateTicks) { + public void runOnMainThreadAtFixedRateInTicks(@NotNull Runnable task, int initialTicks, int rateTicks) { checkDisable(task, (server, plugin) -> server.getScheduler().runTaskTimer(plugin, task, initialTicks, rateTicks)); } } diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/scheduler/FoliaScheduler.java b/bukkit/src/main/java/com/discordsrv/bukkit/scheduler/FoliaScheduler.java index 550b65f4..96851f31 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/scheduler/FoliaScheduler.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/scheduler/FoliaScheduler.java @@ -19,6 +19,7 @@ package com.discordsrv.bukkit.scheduler; import com.discordsrv.bukkit.BukkitDiscordSRV; +import org.jetbrains.annotations.NotNull; public class FoliaScheduler extends AbstractBukkitScheduler implements IFoliaScheduler { @@ -27,17 +28,17 @@ public class FoliaScheduler extends AbstractBukkitScheduler implements IFoliaSch } @Override - public void runOnMainThread(Runnable task) { + public void runOnMainThread(@NotNull Runnable task) { checkDisable(task, (server, plugin) -> IFoliaScheduler.super.runOnMainThread(task)); } @Override - public void runOnMainThreadLaterInTicks(Runnable task, int ticks) { + public void runOnMainThreadLaterInTicks(@NotNull Runnable task, int ticks) { checkDisable(task, (server, plugin) -> IFoliaScheduler.super.runOnMainThreadLaterInTicks(task, ticks)); } @Override - public void runOnMainThreadAtFixedRateInTicks(Runnable task, int initialTicks, int rateTicks) { + public void runOnMainThreadAtFixedRateInTicks(@NotNull Runnable task, int initialTicks, int rateTicks) { checkDisable(task, (server, plugin) -> IFoliaScheduler.super.runOnMainThreadAtFixedRateInTicks(task, initialTicks, rateTicks)); } } diff --git a/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java b/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java index 30ad04b0..187df644 100644 --- a/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java +++ b/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java @@ -538,7 +538,7 @@ public abstract class AbstractDiscordSRV< @Override public final CompletableFuture invokeDisable() { - return CompletableFuture.runAsync(this::disable, scheduler().executorService()); + return scheduler().execute(this::disable); } @Override diff --git a/common/src/main/java/com/discordsrv/common/ServerDiscordSRV.java b/common/src/main/java/com/discordsrv/common/ServerDiscordSRV.java index c58c664a..cf9b4891 100644 --- a/common/src/main/java/com/discordsrv/common/ServerDiscordSRV.java +++ b/common/src/main/java/com/discordsrv/common/ServerDiscordSRV.java @@ -59,7 +59,7 @@ public abstract class ServerDiscordSRV< } public final CompletableFuture invokeServerStarted() { - return CompletableFuture.supplyAsync(() -> { + return scheduler().supply(() -> { if (status().isShutdown()) { // Already shutdown/shutting down, don't bother return null; @@ -76,7 +76,7 @@ public abstract class ServerDiscordSRV< logger().error("Failed to start", t); } return null; - }, scheduler().executorService()); + }); } @OverridingMethodsMustInvokeSuper diff --git a/common/src/main/java/com/discordsrv/common/discord/connection/jda/JDAConnectionManager.java b/common/src/main/java/com/discordsrv/common/discord/connection/jda/JDAConnectionManager.java index 4743f7a2..b2fd8d68 100644 --- a/common/src/main/java/com/discordsrv/common/discord/connection/jda/JDAConnectionManager.java +++ b/common/src/main/java/com/discordsrv/common/discord/connection/jda/JDAConnectionManager.java @@ -283,7 +283,7 @@ public class JDAConnectionManager implements DiscordConnectionManager { throw new IllegalStateException("Cannot reconnect, still active"); } - return connectionFuture = CompletableFuture.runAsync(this::connectInternal, discordSRV.scheduler().executor()); + return connectionFuture = discordSRV.scheduler().execute(this::connectInternal); } private void connectInternal() { @@ -413,10 +413,10 @@ public class JDAConnectionManager implements DiscordConnectionManager { @Override public CompletableFuture reconnect() { - return CompletableFuture.runAsync(() -> { + return discordSRV.scheduler().execute(() -> { shutdown().join(); connect().join(); - }, discordSRV.scheduler().executor()); + }); } @Subscribe(priority = EventPriority.LATE) @@ -427,7 +427,7 @@ public class JDAConnectionManager implements DiscordConnectionManager { @Override public CompletableFuture shutdown(long timeoutMillis) { - return CompletableFuture.runAsync(() -> shutdownInternal(timeoutMillis), discordSRV.scheduler().executor()); + return discordSRV.scheduler().execute(() -> shutdownInternal(timeoutMillis)); } @SuppressWarnings("BusyWait") diff --git a/common/src/main/java/com/discordsrv/common/function/CheckedRunnable.java b/common/src/main/java/com/discordsrv/common/function/CheckedRunnable.java index 49c06698..78127dcb 100644 --- a/common/src/main/java/com/discordsrv/common/function/CheckedRunnable.java +++ b/common/src/main/java/com/discordsrv/common/function/CheckedRunnable.java @@ -19,7 +19,7 @@ package com.discordsrv.common.function; @FunctionalInterface -public interface CheckedRunnable { +public interface CheckedRunnable { - T run() throws Throwable; + void run() throws Throwable; } diff --git a/common/src/main/java/com/discordsrv/common/future/util/CompletableFutureUtil.java b/common/src/main/java/com/discordsrv/common/future/util/CompletableFutureUtil.java index a15f24e6..95acc685 100644 --- a/common/src/main/java/com/discordsrv/common/future/util/CompletableFutureUtil.java +++ b/common/src/main/java/com/discordsrv/common/future/util/CompletableFutureUtil.java @@ -19,12 +19,15 @@ package com.discordsrv.common.future.util; import com.discordsrv.common.DiscordSRV; +import com.discordsrv.common.function.CheckedRunnable; +import com.discordsrv.common.function.CheckedSupplier; import java.time.Duration; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeoutException; @@ -48,20 +51,13 @@ public final class CompletableFutureUtil { @SafeVarargs public static CompletableFuture> combine(CompletableFuture... futures) { - CompletableFuture> future = new CompletableFuture<>(); - CompletableFuture.allOf(futures).whenComplete((v, t) -> { - if (t != null) { - future.completeExceptionally(t); - return; - } - + return CompletableFuture.allOf(futures).thenApply(v -> { List results = new ArrayList<>(); for (CompletableFuture aFuture : futures) { results.add(aFuture.join()); } - future.complete(results); + return results; }); - return future; } public static CompletableFuture timeout(DiscordSRV discordSRV, CompletableFuture future, Duration timeout) { @@ -76,4 +72,28 @@ public final class CompletableFutureUtil { } }); } + + public static CompletableFuture supplyAsync(CheckedSupplier supplier, Executor executor) { + CompletableFuture future = new CompletableFuture<>(); + executor.execute(() -> { + if (future.isCancelled()) { + return; + } + try { + future.complete(supplier.get()); + } catch (InterruptedException ignored) { + Thread.currentThread().interrupt(); + } catch (Throwable t) { + future.completeExceptionally(t); + } + }); + return future; + } + + public static CompletableFuture runAsync(CheckedRunnable runnable, Executor executor) { + return supplyAsync(() -> { + runnable.run(); + return null; + }, executor); + } } diff --git a/common/src/main/java/com/discordsrv/common/http/util/HttpUtil.java b/common/src/main/java/com/discordsrv/common/http/util/HttpUtil.java index 1565abf0..20610b97 100644 --- a/common/src/main/java/com/discordsrv/common/http/util/HttpUtil.java +++ b/common/src/main/java/com/discordsrv/common/http/util/HttpUtil.java @@ -26,8 +26,7 @@ public final class HttpUtil { } public static CompletableFuture readJson(DiscordSRV discordSRV, Request request, Class type) { - CompletableFuture future = new CompletableFuture<>(); - discordSRV.scheduler().run(() -> { + return discordSRV.scheduler().supply(() -> { try (Response response = discordSRV.httpClient().newCall(request).execute()) { ResponseBody responseBody = checkIfResponseSuccessful(request, response); @@ -35,11 +34,8 @@ public final class HttpUtil { if (result == null) { throw new MessageException("Response json cannot be parsed"); } - future.complete(result); - } catch (Throwable t) { - future.completeExceptionally(t); + return result; } }); - return future; } } diff --git a/common/src/main/java/com/discordsrv/common/linking/impl/MinecraftAuthenticationLinker.java b/common/src/main/java/com/discordsrv/common/linking/impl/MinecraftAuthenticationLinker.java index c42beb44..82cebe3b 100644 --- a/common/src/main/java/com/discordsrv/common/linking/impl/MinecraftAuthenticationLinker.java +++ b/common/src/main/java/com/discordsrv/common/linking/impl/MinecraftAuthenticationLinker.java @@ -171,15 +171,7 @@ public class MinecraftAuthenticationLinker extends CachedLinkProvider implements Consumer linked, Consumer unlinked ) { - CompletableFuture> authService = new CompletableFuture<>(); - - discordSRV.scheduler().run(() -> { - try { - authService.complete(authSupplier.get()); - } catch (Throwable t) { - authService.completeExceptionally(t); - } - }); + CompletableFuture> authService = discordSRV.scheduler().supply(authSupplier); if (!canCauseLink) { return authService; } diff --git a/common/src/main/java/com/discordsrv/common/linking/impl/StorageLinker.java b/common/src/main/java/com/discordsrv/common/linking/impl/StorageLinker.java index 95739cb6..4115bd23 100644 --- a/common/src/main/java/com/discordsrv/common/linking/impl/StorageLinker.java +++ b/common/src/main/java/com/discordsrv/common/linking/impl/StorageLinker.java @@ -41,89 +41,68 @@ public class StorageLinker extends CachedLinkProvider implements LinkProvider, L @Override public CompletableFuture> queryUserId(@NotNull UUID playerUUID, boolean canCauseLink) { - return CompletableFuture.supplyAsync(() -> { + return discordSRV.scheduler().supply(() -> { Long value = discordSRV.storage().getUserId(playerUUID); return Optional.ofNullable(value); - }, discordSRV.scheduler().executor()); + }); } @Override public CompletableFuture> queryPlayerUUID(long userId, boolean canCauseLink) { - return CompletableFuture.supplyAsync(() -> { + return discordSRV.scheduler().supply(() -> { UUID value = discordSRV.storage().getPlayerUUID(userId); return Optional.ofNullable(value); - }, discordSRV.scheduler().executor()); + }); } @Override public CompletableFuture createLink(@NotNull UUID playerUUID, long userId) { - return CompletableFuture.runAsync( - () -> discordSRV.storage().createLink(playerUUID, userId), - discordSRV.scheduler().executor() - ); + return discordSRV.scheduler().execute(() -> discordSRV.storage().createLink(playerUUID, userId)); } @Override public CompletableFuture removeLink(@NotNull UUID playerUUID, long userId) { - return CompletableFuture.runAsync( - () -> discordSRV.storage().removeLink(playerUUID, userId), - discordSRV.scheduler().executor() - ); + return discordSRV.scheduler().execute(() -> discordSRV.storage().removeLink(playerUUID, userId)); } @Override public CompletableFuture getCodeLinking(long userId, @NotNull String code) { - return CompletableFuture.supplyAsync( - () -> discordSRV.storage().getLinkingCode(code), - discordSRV.scheduler().executor() - ); + return discordSRV.scheduler().supply(() -> discordSRV.storage().getLinkingCode(code)); } @Override public CompletableFuture removeLinkingCode(@NotNull String code) { - return CompletableFuture.runAsync( - () -> { - UUID player = discordSRV.storage().getLinkingCode(code); - discordSRV.storage().removeLinkingCode(player); - }, - discordSRV.scheduler().executor() - ); + return discordSRV.scheduler().execute(() -> { + UUID player = discordSRV.storage().getLinkingCode(code); + discordSRV.storage().removeLinkingCode(player); + }); } @Override public CompletableFuture removeLinkingCode(@NotNull UUID playerUUID) { - return CompletableFuture.runAsync( - () -> discordSRV.storage().removeLinkingCode(playerUUID), - discordSRV.scheduler().executor() - ); + return discordSRV.scheduler().execute(() -> discordSRV.storage().removeLinkingCode(playerUUID)); } @Override public CompletableFuture getLinkedAccountCount() { - return CompletableFuture.supplyAsync( - () -> discordSRV.storage().getLinkedAccountCount(), - discordSRV.scheduler().executor() - ); + return discordSRV.scheduler().supply(() -> discordSRV.storage().getLinkedAccountCount()); } private final SecureRandom secureRandom = new SecureRandom(); @Override public CompletableFuture getLinkingInstructions(String username, UUID playerUUID, @Nullable Locale locale, @Nullable String requestReason) { - return CompletableFuture.supplyAsync( - () -> { - String code = null; - while (code == null || discordSRV.storage().getLinkingCode(code) != null) { - code = String.valueOf(secureRandom.nextInt(1000000)); - while (code.length() != 6) { - code = "0" + code; - } - } + return discordSRV.scheduler().supply(() -> { + String code = null; + while (code == null || discordSRV.storage().getLinkingCode(code) != null) { + code = String.valueOf(secureRandom.nextInt(1000000)); + while (code.length() != 6) { + code = "0" + code; + } + } - discordSRV.storage().storeLinkingCode(playerUUID, code); - return ComponentUtil.toAPI(Component.text(code)); - }, - discordSRV.scheduler().executor() - ); + discordSRV.storage().storeLinkingCode(playerUUID, code); + return ComponentUtil.toAPI(Component.text(code)); + }); } } diff --git a/common/src/main/java/com/discordsrv/common/linking/requirelinking/requirement/MinecraftAuthRequirement.java b/common/src/main/java/com/discordsrv/common/linking/requirelinking/requirement/MinecraftAuthRequirement.java index a6aa7f59..591d2129 100644 --- a/common/src/main/java/com/discordsrv/common/linking/requirelinking/requirement/MinecraftAuthRequirement.java +++ b/common/src/main/java/com/discordsrv/common/linking/requirelinking/requirement/MinecraftAuthRequirement.java @@ -19,7 +19,6 @@ package com.discordsrv.common.linking.requirelinking.requirement; import com.discordsrv.common.DiscordSRV; -import com.discordsrv.common.function.CheckedSupplier; import me.minecraftauth.lib.AuthService; import me.minecraftauth.lib.account.platform.twitch.SubTier; import me.minecraftauth.lib.exception.LookupException; @@ -165,23 +164,13 @@ public class MinecraftAuthRequirement implements Requirement isMet(Reference atomicReference, UUID player, long userId) { String token = discordSRV.connectionConfig().minecraftAuth.token; T value = atomicReference.getValue(); - if (value == null) { - return supply(() -> test.test(token, player)); - } else { - return supply(() -> testSpecific.test(token, player, value)); - } - } - - private CompletableFuture supply(CheckedSupplier provider) { - CompletableFuture completableFuture = new CompletableFuture<>(); - discordSRV.scheduler().run(() -> { - try { - completableFuture.complete(provider.get()); - } catch (Throwable t) { - completableFuture.completeExceptionally(t); + return discordSRV.scheduler().supply(() -> { + if (value == null) { + return test.test(token, player); + } else { + return testSpecific.test(token, player, value); } }); - return completableFuture; } @FunctionalInterface diff --git a/common/src/main/java/com/discordsrv/common/messageforwarding/game/JoinMessageModule.java b/common/src/main/java/com/discordsrv/common/messageforwarding/game/JoinMessageModule.java index 783f681d..57f3a7e8 100644 --- a/common/src/main/java/com/discordsrv/common/messageforwarding/game/JoinMessageModule.java +++ b/common/src/main/java/com/discordsrv/common/messageforwarding/game/JoinMessageModule.java @@ -41,12 +41,11 @@ import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; public class JoinMessageModule extends AbstractGameMessageModule { - private final Map delayedTasks = new HashMap<>(); + private final Map> delayedTasks = new HashMap<>(); public JoinMessageModule(DiscordSRV discordSRV) { super(discordSRV, "JOIN_MESSAGES"); @@ -79,24 +78,12 @@ public class JoinMessageModule extends AbstractGameMessageModule completableFuture = new CompletableFuture<>(); synchronized (delayedTasks) { - Future future = discordSRV.scheduler().runLater(() -> { - CompletableFuture forward = super.forwardToChannel(event, player, config); + CompletableFuture future = discordSRV.scheduler() + .supplyLater(() -> super.forwardToChannel(event, player, config), Duration.ofMillis(delay)) + .thenCompose(r -> r) + .whenComplete((v, t) -> delayedTasks.remove(playerUUID)); - synchronized (delayedTasks) { - delayedTasks.remove(playerUUID); - } - try { - completableFuture.complete(forward.get()); - } catch (ExecutionException e) { - completableFuture.completeExceptionally(e.getCause()); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - }, Duration.ofMillis(delay)); - delayedTasks.put(playerUUID, () -> { - completableFuture.complete(null); - future.cancel(true); - }); + delayedTasks.put(playerUUID, future); } return completableFuture; } @@ -106,9 +93,9 @@ public class JoinMessageModule extends AbstractGameMessageModule future = delayedTasks.remove(player.uniqueId()); + if (future != null) { + future.cancel(true); logger().info(player.username() + " left within timeout period, join message will not be sent"); } } diff --git a/common/src/main/java/com/discordsrv/common/scheduler/Scheduler.java b/common/src/main/java/com/discordsrv/common/scheduler/Scheduler.java index 244e7f1b..ef38b212 100644 --- a/common/src/main/java/com/discordsrv/common/scheduler/Scheduler.java +++ b/common/src/main/java/com/discordsrv/common/scheduler/Scheduler.java @@ -18,7 +18,9 @@ package com.discordsrv.common.scheduler; -import org.jetbrains.annotations.ApiStatus; +import com.discordsrv.common.function.CheckedRunnable; +import com.discordsrv.common.function.CheckedSupplier; +import com.discordsrv.common.future.util.CompletableFutureUtil; import org.jetbrains.annotations.NotNull; import java.time.Duration; @@ -61,15 +63,37 @@ public interface Scheduler { * * @param task the task */ + @NotNull Future run(@NotNull Runnable task); + @NotNull + default CompletableFuture execute(@NotNull CheckedRunnable task) { + return CompletableFutureUtil.runAsync(task, this::run); + } + + @NotNull + default CompletableFuture supply(@NotNull CheckedSupplier supplier) { + return CompletableFutureUtil.supplyAsync(supplier, this::run); + } + /** * Schedules the given task after the provided amount of milliseconds. * * @param task the task * @param delay the delay before executing the task */ - ScheduledFuture runLater(Runnable task, Duration delay); + @NotNull + ScheduledFuture runLater(@NotNull Runnable task, @NotNull Duration delay); + + @NotNull + default CompletableFuture executeLater(@NotNull CheckedRunnable task, @NotNull Duration delay) { + return CompletableFutureUtil.runAsync(task, t -> runLater(t, delay)); + } + + @NotNull + default CompletableFuture supplyLater(@NotNull CheckedSupplier supplier, @NotNull Duration delay) { + return CompletableFutureUtil.supplyAsync(supplier, task -> runLater(task, delay)); + } /** * Schedules the given task at the given rate. @@ -77,7 +101,7 @@ public interface Scheduler { * @param task the task * @param rate the rate in the given unit */ - @ApiStatus.NonExtendable + @NotNull default ScheduledFuture runAtFixedRate(@NotNull Runnable task, Duration rate) { return runAtFixedRate(task, rate, rate); } @@ -89,7 +113,7 @@ public interface Scheduler { * @param initialDelay the initial delay in the provided unit * @param rate the rate to run the task at in the given unit */ - @ApiStatus.NonExtendable + @NotNull ScheduledFuture runAtFixedRate(@NotNull Runnable task, Duration initialDelay, Duration rate); } diff --git a/common/src/main/java/com/discordsrv/common/scheduler/ServerScheduler.java b/common/src/main/java/com/discordsrv/common/scheduler/ServerScheduler.java index efeb0bc4..e3c87183 100644 --- a/common/src/main/java/com/discordsrv/common/scheduler/ServerScheduler.java +++ b/common/src/main/java/com/discordsrv/common/scheduler/ServerScheduler.java @@ -18,8 +18,12 @@ package com.discordsrv.common.scheduler; -import org.jetbrains.annotations.ApiStatus; +import com.discordsrv.common.function.CheckedRunnable; +import com.discordsrv.common.function.CheckedSupplier; +import com.discordsrv.common.future.util.CompletableFutureUtil; +import org.jetbrains.annotations.NotNull; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @SuppressWarnings("unused") // API @@ -44,7 +48,17 @@ public interface ServerScheduler extends Scheduler { * Runs the provided task on the server's main thread as soon as possible. * @param task the task */ - void runOnMainThread(Runnable task); + void runOnMainThread(@NotNull Runnable task); + + @NotNull + default CompletableFuture supplyOnMainThread(@NotNull CheckedRunnable task) { + return CompletableFutureUtil.runAsync(task, this::runOnMainThread); + } + + @NotNull + default CompletableFuture supplyOnMainThread(@NotNull CheckedSupplier task) { + return CompletableFutureUtil.supplyAsync(task, this::runOnMainThread); + } /** * Runs the provided task in on the server's main thread in the provided amount of ticks. @@ -53,7 +67,17 @@ public interface ServerScheduler extends Scheduler { * @see #TICKS_PER_SECOND * @see #timeToTicks(long, TimeUnit) */ - void runOnMainThreadLaterInTicks(Runnable task, int ticks); + void runOnMainThreadLaterInTicks(@NotNull Runnable task, int ticks); + + @NotNull + default CompletableFuture executeOnMainThreadLaterInTicks(@NotNull CheckedRunnable task, int ticks) { + return CompletableFutureUtil.runAsync(task, t -> runOnMainThreadLaterInTicks(t, ticks)); + } + + @NotNull + default CompletableFuture supplyOnMainThreadLaterInTicks(@NotNull CheckedSupplier task, int ticks) { + return CompletableFutureUtil.supplyAsync(task, t -> runOnMainThreadLaterInTicks(t, ticks)); + } /** * Runs the task on the server's main thread continuously at provided rate in ticks. @@ -61,8 +85,7 @@ public interface ServerScheduler extends Scheduler { * @param task the task * @param rateTicks the rate in ticks */ - @ApiStatus.NonExtendable - default void runOnMainThreadAtFixedRateInTicks(Runnable task, int rateTicks) { + default void runOnMainThreadAtFixedRateInTicks(@NotNull Runnable task, int rateTicks) { runOnMainThreadAtFixedRateInTicks(task, 0, rateTicks); } @@ -73,7 +96,7 @@ public interface ServerScheduler extends Scheduler { * @param initialTicks the initial delay in ticks * @param rateTicks the rate in ticks */ - void runOnMainThreadAtFixedRateInTicks(Runnable task, int initialTicks, int rateTicks); + void runOnMainThreadAtFixedRateInTicks(@NotNull Runnable task, int initialTicks, int rateTicks); } diff --git a/common/src/main/java/com/discordsrv/common/scheduler/StandardScheduler.java b/common/src/main/java/com/discordsrv/common/scheduler/StandardScheduler.java index d8c0c0ee..0f2b8260 100644 --- a/common/src/main/java/com/discordsrv/common/scheduler/StandardScheduler.java +++ b/common/src/main/java/com/discordsrv/common/scheduler/StandardScheduler.java @@ -120,17 +120,17 @@ public class StandardScheduler implements Scheduler { } @Override - public Future run(@NotNull Runnable task) { + public @NotNull Future run(@NotNull Runnable task) { return executorService.submit(wrap(task)); } @Override - public ScheduledFuture runLater(Runnable task, Duration delay) { + public @NotNull ScheduledFuture runLater(@NotNull Runnable task, @NotNull Duration delay) { return scheduledExecutorService.schedule(wrap(task), delay.toMillis(), TimeUnit.MILLISECONDS); } @Override - public ScheduledFuture runAtFixedRate(@NotNull Runnable task, Duration initialDelay, Duration rate) { + public @NotNull ScheduledFuture runAtFixedRate(@NotNull Runnable task, Duration initialDelay, Duration rate) { return scheduledExecutorService.scheduleAtFixedRate(wrap(task), initialDelay.toMillis(), rate.toMillis(), TimeUnit.MILLISECONDS); }