diff --git a/api/src/main/java/com/javadiscord/jdi/internal/api/DiscordRequestDispatcher.java b/api/src/main/java/com/javadiscord/jdi/internal/api/DiscordRequestDispatcher.java index 3dc048b7..f9a67027 100644 --- a/api/src/main/java/com/javadiscord/jdi/internal/api/DiscordRequestDispatcher.java +++ b/api/src/main/java/com/javadiscord/jdi/internal/api/DiscordRequestDispatcher.java @@ -10,6 +10,7 @@ import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Stream; public class DiscordRequestDispatcher implements Runnable { @@ -22,6 +23,7 @@ public class DiscordRequestDispatcher implements Runnable { private final HttpClient httpClient; private final BlockingQueue queue; private final String botToken; + private AtomicBoolean running = new AtomicBoolean(false); private int numberOfRequestsSent; private long timeSinceLastRequest; @@ -41,7 +43,9 @@ public DiscordResponseFuture queue(DiscordRequest discordRequest) { @Override public void run() { - while (true) { + running.set(true); + + while (running.get()) { long currentTime = System.currentTimeMillis(); long elapsed = currentTime - timeSinceLastRequest; @@ -62,6 +66,10 @@ public void run() { } } + public void stop() { + running.set(false); + } + private void sendRequest(DiscordRequestBuilder discordRequestBuilder) { try { HttpRequest.Builder requestBuilder = diff --git a/core/src/main/java/com/javadiscord/jdi/core/Discord.java b/core/src/main/java/com/javadiscord/jdi/core/Discord.java index 6c774c35..f8f5d734 100644 --- a/core/src/main/java/com/javadiscord/jdi/core/Discord.java +++ b/core/src/main/java/com/javadiscord/jdi/core/Discord.java @@ -22,12 +22,13 @@ import java.net.http.HttpResponse; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; public class Discord { private static final Logger LOGGER = LogManager.getLogger(); - private static final Executor EXECUTOR = Executors.newCachedThreadPool(); + private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final String WEBSITE = "https://javadiscord.com/"; @@ -45,6 +46,7 @@ public class Discord { private final List annotatedEventListeners = new ArrayList<>(); private final List eventListeners = new ArrayList<>(); + private WebSocketManager webSocketManager; private Object listenerLoader; public Discord(String botToken) { @@ -134,13 +136,14 @@ private void loadAnnotations() { } public void start() { - WebSocketManager webSocketManager = + this.webSocketManager = new WebSocketManager( new GatewaySetting().setApiVersion(10).setEncoding(GatewayEncoding.JSON), identifyRequest, cache); - WebSocketManagerProxy webSocketManagerProxy = new WebSocketManagerProxy(webSocketManager); + WebSocketManagerProxy webSocketManagerProxy = + new WebSocketManagerProxy(this.webSocketManager); ConnectionDetails connectionDetails = new ConnectionDetails(gateway.url(), botToken, gatewaySetting); ConnectionMediator connectionMediator = @@ -152,6 +155,29 @@ public void start() { EXECUTOR.execute(discordRequestDispatcher); } + public void stop() { + if (this.webSocketManager != null) { + this.webSocketManager.stop(); + } + + discordRequestDispatcher.stop(); + + EXECUTOR.shutdown(); + try { + if (!EXECUTOR.awaitTermination(30, TimeUnit.SECONDS)) { + EXECUTOR.shutdownNow(); + if (!EXECUTOR.awaitTermination(30, TimeUnit.SECONDS)) { + LOGGER.warn( + "Executor failed to shutdown within the specified time limit, some" + + " tasks may still be running"); + } + } + } catch (InterruptedException ie) { + LOGGER.error("Termination was interrupted within {} seconds.", 30); + Thread.currentThread().interrupt(); + } + } + public void startWithoutGatewayEvents() { EXECUTOR.execute(discordRequestDispatcher); }