ScheduledExecutorService перестает работать случайно
У меня довольно сложный бот, использующий API-интерфейс Discord JDA, и для периодической проверки изменений статуса у меня есть ScheduledExecutorService
, Проблема заключается в том, что когда я вводю команды для бота, есть случайный (?) Шанс, что служба просто перестанет работать, что делает всю программу не отвечающей без какой-либо ошибки в трассировке стека. Я вывел это, поставив простой счетчик таймера, и он, кажется, просто останавливается случайным образом (не совсем, скорее, у него нет определенного шаблона). Это класс проверки:
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.User;
import us.verif.bot.sql.Sql;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class PeriodicCheck implements Runnable {
int i = 0;
private JDA jda;
public PeriodicCheck(JDA jda) {
this.jda = jda;
}
public void run() {
i++;
System.out.println(i);
try {
Connection connection = DataSource.getConnection();
connection.setCatalog("verifus");
PreparedStatement preparedStatement = connection.prepareStatement("select * from `activatedservers` where `expireDate` <= NOW()");
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
String guildId = Config.getGuildId();
User user = jda.getGuildById(guildId).getOwner().getUser();
String server = jda.getGuildById(guildId).getName();
user.openPrivateChannel().queue((channel) -> channel.sendMessage("Your Verifus activation for your server `" + server + "` has expired. \nVisit https://verif.us/ to purchase.").queue());
}
connection.close();
Sql.deleteExpiredGuilds();
Connection connection1 = DataSource.getConnection();
connection1.setCatalog(Config.getGuildId());
PreparedStatement preparedStatement1 = connection1.prepareStatement("select * from `verifiedusers` where `expireDate` <= NOW()");
ResultSet rs1 = preparedStatement1.executeQuery();
while (rs1.next()) {
User user = jda.getUserById(rs1.getString("discordId"));
String serverName = jda.getGuildById(Config.getGuildId()).getName();
Guild guild = jda.getGuildById(Config.getGuildId());
String role = rs1.getString("roleId");
user.openPrivateChannel().queue((channel) -> channel.sendMessage("Your role `" + jda.getRoleById(role).getName() + "` in the server `" + serverName + "` has expired.").queue());
guild.getController().removeSingleRoleFromMember(guild.getMemberById(rs1.getString("discordId")), jda.getRoleById(role)).queue();
}
connection1.close();
Sql.deleteExpiredUsers();
} catch (Exception e) {
e.printStackTrace();
}
}
}
А вот часть класса Main, который запускает службу:
PeriodicCheck periodicCheck = new PeriodicCheck(api);
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
try {
scheduledExecutorService.scheduleAtFixedRate(periodicCheck, 0, 1, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
}
Если я не ошибся при их создании, то я вполне уверен, что где-то еще в моей программе это вызвано, и это будет трудно найти.
Обратите внимание, что это произошло раньше, когда я использовал TimerTask
вместо ScheduledExecutorService
И это было потому, что я не закрывал свои SQL-соединения, но я сделал все возможное, чтобы закрыть их в своем коде.
Если ничего не происходит, я могу предоставить больше классов своей программы, хотя я не знаю, какая из них вызывает, потому что это происходит случайным образом с каждой командой. Может ли это быть из-за моего компьютера / интернета? Я запускаю это дома с моим персональным компьютером для тестирования.
В моем классе проверки также есть два других метода, которые явно не указаны, вот они:Sql.deleteExpiredGuilds
:
try {
Connection connection = DataSource.getConnection();
connection.setCatalog("verifus");
connection.prepareStatement("delete from activatedservers where expireDate <= NOW()").executeUpdate();
connection.close();
} catch (SQLException e) { e.printStackTrace(); }
}
Sql.deleteExpiredUsers
:
try {
Connection connection = DataSource.getConnection();
connection.setCatalog(Config.getGuildId());
connection.prepareStatement("delete from verifiedusers where expireDate <= NOW()").executeUpdate();
connection.close();
} catch (SQLException e) { e.printStackTrace(); }
}