Threads not being terminated after closing application

102 Views Asked by At

I'm trying to create a discord bot using the Discord4J api, but when I try to run the app from IntelliJ or CMD, when I exit the app, the bot is still active and in my task manager I can see the active threads created by this app, the only way is to manually end the tasks from task manager.

I followed the steps provided by the official Discord4J wiki Music-Bot-Tutorial, It mentions If you wish to disconnect your bot, click on the Exit button in the console., but this is not happening with my program.

This is the code I am using:

public static void main(String[] args) throws Exception {
  DiscordClient client = DiscordClientBuilder.create(BOT_TOKEN).build();
  GatewayDiscordClient gateway = client.login().block();

  gateway.onDisconnect().block();
}

Gradle only gives this details when I try to stop the application Execution failed for task ':SampleBot.main()'. Build cancelled while executing task ':SampleBot.main()'

2

There are 2 best solutions below

0
Azn9 On

By clicking the "stop" button, you're forcibly closing the application without letting it terminate properly. If the bot still appears online, it is because due to this force close, it never sends a "disconnect" message to Discord. The threads you see are from gradle, which runs as a daemon by default, meaning it is always active to launch the applications faster the next time you use it.

If you want to shut down your bot correctly, you should add some logic in your code by listening for input in the console by example and calling client.logout().block();.

0
Muhammad Tariq On

It seems like the issue might be related to how you are handling the termination of your Discord bot application. When you run the bot using the code you provided, it blocks the main thread with gateway.onDisconnect().block();, preventing the application from properly terminating when you try to exit it.

To gracefully shut down the Discord bot when you want to exit the application, you can use a CountDownLatch. Here's how you can modify your code to achieve this:

```java
import reactor.core.publisher.Mono;
import java.util.concurrent.CountDownLatch;

public class SampleBot {
    private static final String BOT_TOKEN = "your_bot_token_here";

    public static void main(String[] args) throws Exception {
        DiscordClient client = DiscordClientBuilder.create(BOT_TOKEN).build();
        GatewayDiscordClient gateway = client.login().block();

        // Initialize the latch with 1 permit
        CountDownLatch latch = new CountDownLatch(1);

        // Add a shutdown hook to gracefully disconnect the bot when the application is terminated
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.out.println("Shutting down bot...");
            gateway.logout().block();
            latch.countDown();
        }));

        // Wait until the latch reaches 0 (i.e., the bot is disconnected)
        latch.await();
    }
}
```

With this modification, when you run the bot, it will start and block the main thread with latch.await(). However, when you exit the application (for example, by clicking the Exit button in the console), the shutdown hook will be triggered, logging out the bot and releasing the latch, allowing the main thread to continue and the application to terminate gracefully.

By using this approach, you should no longer see active threads in your task manager after exiting the application, as the bot will be disconnected properly before the application terminates.