From dbce0832a3d1e60faf2bbdc5422042cc651d0edf Mon Sep 17 00:00:00 2001 From: Vankka Date: Mon, 22 Aug 2022 18:46:12 +0300 Subject: [PATCH] Change everything to a central OkHttpClient, reduce amount of threads that can be used, adjust some other stuff --- .../interaction/command/CommandType.java | 23 +++++++++ .../impl/SendableDiscordMessageImpl.java | 2 +- .../AbstractCommandInteractionEvent.java | 23 +++++++++ .../command/CommandRegisterEvent.java | 23 +++++++++ build.gradle | 2 +- .../bukkit/integration/VaultIntegration.java | 2 +- common/build.gradle | 5 +- .../discordsrv/common/AbstractDiscordSRV.java | 49 ++++++++++++++----- .../com/discordsrv/common/DiscordSRV.java | 2 +- .../common/discord/api/DiscordAPIImpl.java | 2 +- .../discord/api/DiscordCommandRegistry.java | 18 +++++++ .../connection/jda/JDAConnectionManager.java | 10 +--- .../connection/jda/JDAEventManager.java | 9 ++-- .../provider/AbstractPlayerProvider.java | 4 +- .../common/scheduler/Scheduler.java | 9 ---- .../common/scheduler/StandardScheduler.java | 21 ++++---- 16 files changed, 152 insertions(+), 52 deletions(-) diff --git a/api/src/main/java/com/discordsrv/api/discord/entity/interaction/command/CommandType.java b/api/src/main/java/com/discordsrv/api/discord/entity/interaction/command/CommandType.java index 58683954..f733be3e 100644 --- a/api/src/main/java/com/discordsrv/api/discord/entity/interaction/command/CommandType.java +++ b/api/src/main/java/com/discordsrv/api/discord/entity/interaction/command/CommandType.java @@ -1,3 +1,26 @@ +/* + * This file is part of the DiscordSRV API, licensed under the MIT License + * Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + package com.discordsrv.api.discord.entity.interaction.command; import com.discordsrv.api.discord.entity.JDAEntity; diff --git a/api/src/main/java/com/discordsrv/api/discord/entity/message/impl/SendableDiscordMessageImpl.java b/api/src/main/java/com/discordsrv/api/discord/entity/message/impl/SendableDiscordMessageImpl.java index 45143377..e34a352b 100644 --- a/api/src/main/java/com/discordsrv/api/discord/entity/message/impl/SendableDiscordMessageImpl.java +++ b/api/src/main/java/com/discordsrv/api/discord/entity/message/impl/SendableDiscordMessageImpl.java @@ -295,7 +295,7 @@ public class SendableDiscordMessageImpl implements SendableDiscordMessage { builder.setContent(placeholders.apply(builder.getContent())); List embeds = new ArrayList<>(builder.getEmbeds()); - builder.getEmbeds().clear(); + builder.getEmbeds().forEach(builder::removeEmbed); for (DiscordMessageEmbed embed : embeds) { DiscordMessageEmbed.Builder embedBuilder = embed.toBuilder(); diff --git a/api/src/main/java/com/discordsrv/api/discord/events/interaction/command/AbstractCommandInteractionEvent.java b/api/src/main/java/com/discordsrv/api/discord/events/interaction/command/AbstractCommandInteractionEvent.java index 69539341..c46d17b0 100644 --- a/api/src/main/java/com/discordsrv/api/discord/events/interaction/command/AbstractCommandInteractionEvent.java +++ b/api/src/main/java/com/discordsrv/api/discord/events/interaction/command/AbstractCommandInteractionEvent.java @@ -1,3 +1,26 @@ +/* + * This file is part of the DiscordSRV API, licensed under the MIT License + * Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + package com.discordsrv.api.discord.events.interaction.command; import com.discordsrv.api.discord.entity.DiscordUser; diff --git a/api/src/main/java/com/discordsrv/api/discord/events/interaction/command/CommandRegisterEvent.java b/api/src/main/java/com/discordsrv/api/discord/events/interaction/command/CommandRegisterEvent.java index e19b31aa..220817a8 100644 --- a/api/src/main/java/com/discordsrv/api/discord/events/interaction/command/CommandRegisterEvent.java +++ b/api/src/main/java/com/discordsrv/api/discord/events/interaction/command/CommandRegisterEvent.java @@ -1,3 +1,26 @@ +/* + * This file is part of the DiscordSRV API, licensed under the MIT License + * Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + package com.discordsrv.api.discord.events.interaction.command; import com.discordsrv.api.discord.entity.interaction.command.Command; diff --git a/build.gradle b/build.gradle index 3ca2dea1..0e405f26 100644 --- a/build.gradle +++ b/build.gradle @@ -41,7 +41,7 @@ subprojects { repositories { // Snapshot repositories //maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } - mavenLocal() + //mavenLocal() maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' } maven { 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 6517b1b6..a2105373 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/integration/VaultIntegration.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/integration/VaultIntegration.java @@ -120,7 +120,7 @@ public class VaultIntegration extends PluginIntegration implem } }; if (async) { - discordSRV.scheduler().runFork(runnable); + discordSRV.scheduler().run(runnable); } else { discordSRV.scheduler().runOnMainThread(runnable); } diff --git a/common/build.gradle b/common/build.gradle index 3a695bde..797cd570 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -40,7 +40,10 @@ dependencies { api(libs.dependencydownload.runtime) // Discord Webhooks - runtimeDownloadApi(libs.webhooks) + runtimeDownloadApi(libs.webhooks) { + // okhttp is already included + exclude group: 'com.squareup.okhttp3', module: 'okhttp' + } // Apache Commons runtimeDownloadApi(libs.commons.lang) diff --git a/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java b/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java index 54747352..d4835764 100644 --- a/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java +++ b/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java @@ -73,6 +73,9 @@ import com.discordsrv.common.storage.Storage; import com.discordsrv.common.storage.StorageType; import com.fasterxml.jackson.databind.ObjectMapper; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.JDAInfo; +import okhttp3.ConnectionPool; +import okhttp3.Dispatcher; import okhttp3.OkHttpClient; import okhttp3.Request; import org.intellij.lang.annotations.Language; @@ -134,18 +137,7 @@ public abstract class AbstractDiscordSRV { - Request original = chain.request(); - return chain.proceed( - original.newBuilder() - .removeHeader("User-Agent") - .addHeader("User-Agent", "DiscordSRV/" + version()) - .build() - ); - }) - .callTimeout(1, TimeUnit.MINUTES) - .build(); + private OkHttpClient httpClient; private final ObjectMapper objectMapper = new ObjectMapper(); // Internal @@ -174,6 +166,39 @@ public abstract class AbstractDiscordSRV { + Request original = chain.request(); + String host = original.url().host(); + boolean isDiscord = host.endsWith("discord.com") + || host.endsWith("discordapp.com") + || host.endsWith("discord.gg"); + + String userAgent = isDiscord + ? "DiscordBot (https://github.com/DiscordSRV/DiscordSRV, " + version() + ")" + + " (" + JDAInfo.GITHUB + ", " + JDAInfo.VERSION + ")" + : "DiscordSRV/" + version(); + + return chain.proceed( + original.newBuilder() + .removeHeader("User-Agent") + .addHeader("User-Agent", userAgent) + .build() + ); + }) + .connectTimeout(20, TimeUnit.SECONDS) + .readTimeout(20, TimeUnit.SECONDS) + .writeTimeout(20, TimeUnit.SECONDS) + .build(); } protected URL getManifest() { diff --git a/common/src/main/java/com/discordsrv/common/DiscordSRV.java b/common/src/main/java/com/discordsrv/common/DiscordSRV.java index 87bba514..9708504a 100644 --- a/common/src/main/java/com/discordsrv/common/DiscordSRV.java +++ b/common/src/main/java/com/discordsrv/common/DiscordSRV.java @@ -134,7 +134,7 @@ public interface DiscordSRV extends DiscordSRVApi { @ApiStatus.NonExtendable default Caffeine caffeineBuilder() { return (Caffeine) Caffeine.newBuilder() - .executor(scheduler().forkJoinPool()); + .executor(scheduler().executorService()); } OkHttpClient httpClient(); ObjectMapper json(); diff --git a/common/src/main/java/com/discordsrv/common/discord/api/DiscordAPIImpl.java b/common/src/main/java/com/discordsrv/common/discord/api/DiscordAPIImpl.java index 4b86753c..d3850921 100644 --- a/common/src/main/java/com/discordsrv/common/discord/api/DiscordAPIImpl.java +++ b/common/src/main/java/com/discordsrv/common/discord/api/DiscordAPIImpl.java @@ -450,7 +450,7 @@ public class DiscordAPIImpl implements DiscordAPI { @Override public Command.RegistrationResult registerCommand(Command command) { - return commandRegistry.register(command); + return commandRegistry.register(command, false); } @Override diff --git a/common/src/main/java/com/discordsrv/common/discord/api/DiscordCommandRegistry.java b/common/src/main/java/com/discordsrv/common/discord/api/DiscordCommandRegistry.java index d939407e..5e708896 100644 --- a/common/src/main/java/com/discordsrv/common/discord/api/DiscordCommandRegistry.java +++ b/common/src/main/java/com/discordsrv/common/discord/api/DiscordCommandRegistry.java @@ -1,3 +1,21 @@ +/* + * This file is part of DiscordSRV, licensed under the GPLv3 License + * Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package com.discordsrv.common.discord.api; import com.discordsrv.api.discord.entity.JDAEntity; 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 095a2418..5e92beef 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 @@ -52,8 +52,6 @@ import net.dv8tion.jda.api.utils.ChunkingFilter; import net.dv8tion.jda.api.utils.MemberCachePolicy; import net.dv8tion.jda.internal.entities.ReceivedMessage; import net.dv8tion.jda.internal.hooks.EventManagerProxy; -import net.dv8tion.jda.internal.utils.IOUtil; -import okhttp3.OkHttpClient; import org.jetbrains.annotations.NotNull; import javax.security.auth.login.LoginException; @@ -271,13 +269,7 @@ public class JDAConnectionManager implements DiscordConnectionManager { jdaBuilder.setCallbackPool(discordSRV.scheduler().forkJoinPool()); jdaBuilder.setGatewayPool(gatewayPool); jdaBuilder.setRateLimitPool(rateLimitPool, true); - - OkHttpClient.Builder httpBuilder = IOUtil.newHttpClientBuilder(); - // These 3 are 10 seconds by default - httpBuilder.connectTimeout(20, TimeUnit.SECONDS); - httpBuilder.readTimeout(20, TimeUnit.SECONDS); - httpBuilder.writeTimeout(20, TimeUnit.SECONDS); - jdaBuilder.setHttpClientBuilder(httpBuilder); + jdaBuilder.setHttpClient(discordSRV.httpClient()); WebSocketFactory webSocketFactory = new WebSocketFactory(); jdaBuilder.setWebsocketFactory(webSocketFactory); diff --git a/common/src/main/java/com/discordsrv/common/discord/connection/jda/JDAEventManager.java b/common/src/main/java/com/discordsrv/common/discord/connection/jda/JDAEventManager.java index 49a0ae20..b4cbdfd0 100644 --- a/common/src/main/java/com/discordsrv/common/discord/connection/jda/JDAEventManager.java +++ b/common/src/main/java/com/discordsrv/common/discord/connection/jda/JDAEventManager.java @@ -23,7 +23,6 @@ import net.dv8tion.jda.api.events.GenericEvent; import net.dv8tion.jda.api.hooks.IEventManager; import org.jetbrains.annotations.NotNull; -import java.util.Collections; import java.util.List; public class JDAEventManager implements IEventManager { @@ -34,8 +33,10 @@ public class JDAEventManager implements IEventManager { this.discordSRV = discordSRV; } - private void illegalUse() { - throw new RuntimeException("The JDA event manager may not be used while using DiscordSRV. Please use DiscordSRV's own event bus to listen for JDA events"); + @SuppressWarnings("UnusedReturnValue") + private T illegalUse() { + throw new RuntimeException("The JDA event manager may not be used while using DiscordSRV. " + + "Please use DiscordSRV's own event bus to listen for JDA events"); } @Override @@ -56,6 +57,6 @@ public class JDAEventManager implements IEventManager { @NotNull @Override public List getRegisteredListeners() { - return Collections.emptyList(); + return illegalUse(); } } diff --git a/common/src/main/java/com/discordsrv/common/player/provider/AbstractPlayerProvider.java b/common/src/main/java/com/discordsrv/common/player/provider/AbstractPlayerProvider.java index d34119db..dc5718a4 100644 --- a/common/src/main/java/com/discordsrv/common/player/provider/AbstractPlayerProvider.java +++ b/common/src/main/java/com/discordsrv/common/player/provider/AbstractPlayerProvider.java @@ -43,14 +43,14 @@ public abstract class AbstractPlayerProvider discordSRV.eventBus().publish(new PlayerConnectedEvent(player, initial))); + discordSRV.scheduler().run(() -> discordSRV.eventBus().publish(new PlayerConnectedEvent(player, initial))); } protected void removePlayer(UUID uuid) { T player = this.players.remove(uuid); if (player != null) { allPlayers.remove(player); - discordSRV.scheduler().runFork(() -> discordSRV.eventBus().publish(new PlayerDisconnectedEvent(player))); + discordSRV.scheduler().run(() -> discordSRV.eventBus().publish(new PlayerDisconnectedEvent(player))); } } 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 8e81784c..84d13782 100644 --- a/common/src/main/java/com/discordsrv/common/scheduler/Scheduler.java +++ b/common/src/main/java/com/discordsrv/common/scheduler/Scheduler.java @@ -62,15 +62,6 @@ public interface Scheduler { */ Future run(@NotNull Runnable task); - /** - * Runs the provided {@link Runnable} on a {@link ForkJoinPool} as soon as possible. - * Please view the docs of {@link ForkJoinPool} for benefits. - * - * @param task the task - */ - @ApiStatus.NonExtendable - ForkJoinTask runFork(@NotNull Runnable task); - /** * Schedules the given task to run after the provided time in the provided {@link TimeUnit}. * 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 237090a3..e614bd71 100644 --- a/common/src/main/java/com/discordsrv/common/scheduler/StandardScheduler.java +++ b/common/src/main/java/com/discordsrv/common/scheduler/StandardScheduler.java @@ -40,18 +40,24 @@ public class StandardScheduler implements Scheduler { this( discordSRV, new ThreadPoolExecutor( - 4, /* Core pool size */ - 16, /* Max pool size */ + 1, /* Core pool size */ + 20, /* Max pool size */ 60, TimeUnit.SECONDS, /* Timeout */ new SynchronousQueue<>(), new CountingThreadFactory(Scheduler.THREAD_NAME_PREFIX + "Executor #%s") ), new ScheduledThreadPoolExecutor( - 2, /* Core pool size */ + 0, /* Core pool size */ new CountingThreadFactory(Scheduler.THREAD_NAME_PREFIX + "Scheduled Executor #%s") ), new ForkJoinPool( - Math.max(1, Runtime.getRuntime().availableProcessors() - 1), /* Parallelism - not core pool size */ + /* parallelism */ + Math.min( + /* max of 10 */ + 10, + /* cpu cores - 1 or at least 1 */ + Math.max(1, Runtime.getRuntime().availableProcessors() - 1) + ), new CountingForkJoinWorkerThreadFactory(Scheduler.THREAD_NAME_PREFIX + "ForkJoinPool Worker #%s"), null, false /* FIFO */ @@ -113,11 +119,6 @@ public class StandardScheduler implements Scheduler { return executorService.submit(wrap(task)); } - @Override - public ForkJoinTask runFork(@NotNull Runnable task) { - return forkJoinPool.submit(wrap(task)); - } - @Override public ScheduledFuture runLater(Runnable task, long timeMillis) { return scheduledExecutorService.schedule(wrap(task), timeMillis, TimeUnit.MILLISECONDS); @@ -132,7 +133,7 @@ public class StandardScheduler implements Scheduler { @Override public void execute(@NotNull Runnable command) { - runFork(command); + run(command); } } }