diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/SlashCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/SlashCommand.java index 6aca0e5bc3..0960b223e7 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/SlashCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/SlashCommand.java @@ -92,6 +92,10 @@ public interface SlashCommand { * Triggered by the command system when a slash command corresponding to this implementation * (based on {@link #getData()} has been triggered. *

+ * This method may be called multi-threaded. In particular, there are no guarantees that it will + * be executed on the same thread repeatedly or on the same thread that other event methods have + * been called on. + *

* Details are available in the given event and the event also enables implementations to * respond to it. *

@@ -134,6 +138,10 @@ public interface SlashCommand { * Triggered by the command system when a button corresponding to this implementation (based on * {@link #getData()} has been clicked. *

+ * This method may be called multi-threaded. In particular, there are no guarantees that it will + * be executed on the same thread repeatedly or on the same thread that other event methods have + * been called on. + *

* Details are available in the given event and the event also enables implementations to * respond to it. *

@@ -150,6 +158,10 @@ public interface SlashCommand { * Triggered by the command system when a selection menu corresponding to this implementation * (based on {@link #getData()} has been clicked. *

+ * This method may be called multi-threaded. In particular, there are no guarantees that it will + * be executed on the same thread repeatedly or on the same thread that other event methods have + * been called on. + *

* Details are available in the given event and the event also enables implementations to * respond to it. *

diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/system/CommandSystem.java b/application/src/main/java/org/togetherjava/tjbot/commands/system/CommandSystem.java index de122d64a6..fd60e4c283 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/system/CommandSystem.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/system/CommandSystem.java @@ -22,6 +22,8 @@ import org.togetherjava.tjbot.db.Database; import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.function.Function; import java.util.stream.Collectors; @@ -40,6 +42,7 @@ public final class CommandSystem extends ListenerAdapter implements SlashCommandProvider { private static final Logger logger = LoggerFactory.getLogger(CommandSystem.class); private static final String RELOAD_COMMAND = "reload"; + private static final ExecutorService COMMAND_SERVICE = Executors.newCachedThreadPool(); private final Map nameToSlashCommands; /** @@ -80,7 +83,9 @@ public CommandSystem(@NotNull Database database) { public void onReady(@NotNull ReadyEvent event) { // Register reload on all guilds logger.debug("JDA is ready, registering reload command"); - event.getJDA().getGuildCache().forEach(this::registerReloadCommand); + event.getJDA() + .getGuildCache() + .forEach(guild -> COMMAND_SERVICE.execute(() -> registerReloadCommand(guild))); // NOTE We do not have to wait for reload to complete for the command system to be ready // itself logger.debug("Command system is now ready"); @@ -90,21 +95,22 @@ public void onReady(@NotNull ReadyEvent event) { public void onSlashCommand(@NotNull SlashCommandEvent event) { logger.debug("Received slash command '{}' (#{}) on guild '{}'", event.getName(), event.getId(), event.getGuild()); - requireSlashCommand(event.getName()).onSlashCommand(event); + COMMAND_SERVICE.execute(() -> requireSlashCommand(event.getName()).onSlashCommand(event)); } @Override public void onButtonClick(@NotNull ButtonClickEvent event) { logger.debug("Received button click '{}' (#{}) on guild '{}'", event.getComponentId(), event.getId(), event.getGuild()); - forwardComponentCommand(event, SlashCommand::onButtonClick); + COMMAND_SERVICE.execute(() -> forwardComponentCommand(event, SlashCommand::onButtonClick)); } @Override public void onSelectionMenu(@NotNull SelectionMenuEvent event) { logger.debug("Received selection menu event '{}' (#{}) on guild '{}'", event.getComponentId(), event.getId(), event.getGuild()); - forwardComponentCommand(event, SlashCommand::onSelectionMenu); + COMMAND_SERVICE + .execute(() -> forwardComponentCommand(event, SlashCommand::onSelectionMenu)); } private void registerReloadCommand(@NotNull Guild guild) {