Updated threadmanager and refactored code

This commit is contained in:
anthorob committed 2021-09-21 14:03:50 -04:00
1 parent 62fe015ffa
commit c11af0da51
11 files changed
+103 -78

No files matched your search

+1 -1
View File
@@ -42,7 +42,7 @@ public class MusicBot {
jda.getPresence().setActivity(Activity.watching("me load...")); jda.getPresence().setActivity(Activity.watching("me load..."));
jda.addEventListener(new NewCommandListener(), new EditHandler()); jda.addEventListener(new NewCommandListener(), new EditHandler());
WebApi webserver = new WebApi(); new WebApi();
jda.getPresence().setActivity(Activity.watching("you")); jda.getPresence().setActivity(Activity.watching("you"));
+60 -36
View File
@@ -1,68 +1,92 @@
package netneutrality; package netneutrality;
/*
* Copyright (c) anthorob
*
* This file is closed-source. It should not be distributed or copied in any way or form
*/
import netneutrality.thread.BaseThread; import netneutrality.thread.BaseThread;
import netneutrality.utils.Settings;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.concurrent.ExecutorService; import java.util.Map;
import java.util.concurrent.Executors; import java.util.concurrent.*;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ThreadManager { public class ThreadManager {
private static ThreadManager INSTANCE; public enum ExecutorType {
SINGLE, SCHEDULED, FIXED
}
private static final Map<String, ExecutorService> executors = new ConcurrentHashMap<>();
private final static Logger logger = LoggerFactory.getLogger(ThreadManager.class); private final static Logger logger = LoggerFactory.getLogger(ThreadManager.class);
public static final ExecutorService executor = Executors.newSingleThreadExecutor(new BaseThread("executor"));
public static final ExecutorService dBExecutor = Executors.newSingleThreadExecutor(new BaseThread("db-action"));
public static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5, new BaseThread("scheduled-action"));
public static ExecutorService getExecutor(String name) {
public ThreadManager() { return executors.computeIfAbsent(name, s -> Executors.newSingleThreadExecutor(new BaseThread(name)));
} }
public static ThreadManager getInstance() { public static ExecutorService getExecutor(String name, ExecutorType type) {
if(INSTANCE == null) { ExecutorService executor;
INSTANCE = new ThreadManager();
switch (type) {
case FIXED:
executor = executors.computeIfAbsent(name, s -> Executors.newFixedThreadPool(5, new BaseThread(name)));
break;
case SCHEDULED:
executor = executors.computeIfAbsent(name, s -> Executors.newScheduledThreadPool(5, new BaseThread(name)));
break;
default:
executor = executors.computeIfAbsent(name, s -> Executors.newSingleThreadExecutor(new BaseThread(name)));
} }
return INSTANCE; return executor;
}
public static ExecutorService getExecutor(String name, ExecutorType type, Integer poolSize) {
ExecutorService executor;
switch (type) {
case FIXED:
executor = executors.computeIfAbsent(name, s -> Executors.newFixedThreadPool(poolSize, new BaseThread(name)));
break;
case SCHEDULED:
executor = executors.computeIfAbsent(name, s -> Executors.newScheduledThreadPool(poolSize, new BaseThread(name)));
break;
default:
executor = executors.computeIfAbsent(name, s -> Executors.newSingleThreadExecutor(new BaseThread(name)));
}
return executor;
}
public static Future<?> dispatch(ExecutorService executor, Runnable task) {
return executor.submit(task);
}
public static <T> Future<T> dispatch(ExecutorService executor, Callable<T> task) {
return executor.submit(task);
} }
public static void shutdownExecutor() { public static void shutdownExecutor() {
logger.info("[Executor] Shutting down..."); logger.debug("[Executor] Shutting down...");
try { try {
executor.shutdown(); for (ExecutorService ex : executors.values()) {
scheduler.shutdown(); ex.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS); ex.awaitTermination(5, TimeUnit.SECONDS);
scheduler.awaitTermination(5, TimeUnit.SECONDS); }
} }
catch (InterruptedException e) { catch (InterruptedException e) {
logger.warn("[Executor] Running tasks interrupted"); logger.warn("[Executor] Running tasks interrupted");
} }
finally { finally {
if (!executor.isTerminated()) { executors.forEach((name, ex) -> {
logger.warn("[Executor] Forcing shutdown of running tasks.."); if (!ex.isTerminated()) {
executor.shutdownNow(); logger.warn("[Executor: " + name + "] Forcing shutdown of running tasks..");
} ex.shutdownNow();
}
if (!scheduler.isTerminated()) { });
logger.warn("[Executor] Forcing shutdown of running tasks..");
scheduler.shutdownNow();
}
} }
logger.info("[Executor] Shutdown finished!"); logger.debug("[Executor] Shutdown finished!");
} }
@@ -8,17 +8,15 @@ package netneutrality.db;
*/ */
import netneutrality.ThreadManager; import netneutrality.ThreadManager;
import netneutrality.db.entities.EntityInterface;
import netneutrality.db.models.MTableModel; import netneutrality.db.models.MTableModel;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.concurrent.Callable; import java.util.concurrent.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.function.Consumer; import java.util.function.Consumer;
public class AsyncMySqlAction { public class AsyncMySqlAction {
private final ExecutorService executor = ThreadManager.getExecutor("db-action", ThreadManager.ExecutorType.SINGLE);
private final String sqlString; private final String sqlString;
private final Object[] params; private final Object[] params;
private final MysqlDatabase.CommandType type; private final MysqlDatabase.CommandType type;
@@ -39,24 +37,24 @@ public class AsyncMySqlAction {
public void async(Consumer<MTableModel> success) { public void async(Consumer<MTableModel> success) {
switch (type) { switch (type) {
case INSERT: case INSERT:
ThreadManager.dBExecutor.submit(() -> { ThreadManager.dispatch(executor, () -> {
db.insert(this.sqlString, this.params); db.insert(this.sqlString, this.params);
}); });
break; break;
case UPDATE: case UPDATE:
ThreadManager.dBExecutor.submit(() -> { ThreadManager.dispatch(executor, () -> {
db.update(this.sqlString, this.params); db.update(this.sqlString, this.params);
}); });
break; break;
case DELETE: case DELETE:
ThreadManager.dBExecutor.submit(() -> { ThreadManager.dispatch(executor, () -> {
db.delete(this.sqlString, this.params); db.delete(this.sqlString, this.params);
}); });
break; break;
case SELECT: case SELECT:
ThreadManager.dBExecutor.submit(() -> { ThreadManager.dispatch(executor, () -> {
ResultSet result = db.prepareAndExecute(this.sqlString, this.params); ResultSet result = db.prepareAndExecute(this.sqlString, this.params);
MTableModel table = MysqlDatabase.convertToTableModel(result); MTableModel table = MysqlDatabase.convertToTableModel(result);
@@ -70,17 +68,17 @@ public class AsyncMySqlAction {
try { try {
switch (type) { switch (type) {
case INSERT: case INSERT:
ThreadManager.dBExecutor.submit(() -> { ThreadManager.dispatch(executor, () -> {
db.insert(this.sqlString, this.params); db.insert(this.sqlString, this.params);
}).get(); }).get();
case UPDATE: case UPDATE:
ThreadManager.dBExecutor.submit(() -> { ThreadManager.dispatch(executor, () -> {
db.update(this.sqlString, this.params); db.update(this.sqlString, this.params);
}).get(); }).get();
case DELETE: case DELETE:
ThreadManager.dBExecutor.submit(() -> { ThreadManager.dispatch(executor, () -> {
db.delete(this.sqlString, this.params); db.delete(this.sqlString, this.params);
}).get(); }).get();
@@ -92,7 +90,7 @@ public class AsyncMySqlAction {
return table; return table;
}; };
Future<MTableModel> future = ThreadManager.dBExecutor.submit(task); Future<MTableModel> future = ThreadManager.dispatch(executor, task);
return future.get(); return future.get();
} }
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
@@ -5,6 +5,7 @@ import java.lang.reflect.Modifier;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import netneutrality.MusicBot; import netneutrality.MusicBot;
@@ -70,7 +71,7 @@ public class DBController {
if (controllers.isEmpty()) if (controllers.isEmpty())
loadControllers(); loadControllers();
ThreadManager.scheduler.scheduleWithFixedDelay(() -> { ((ScheduledExecutorService) ThreadManager.getExecutor("db-keepalive", ThreadManager.ExecutorType.SCHEDULED, 5)).scheduleWithFixedDelay(() -> {
DBController.get().query("SELECT 1;"); DBController.get().query("SELECT 1;");
}, 0, 120, TimeUnit.SECONDS); }, 0, 120, TimeUnit.SECONDS);
} }
@@ -80,7 +80,8 @@ public class DBBlacklist extends AbstractController {
@Deprecated @Deprecated
public void getBlacklistForWord(String word, String serverId, Consumer<MBlacklist> success) { public void getBlacklistForWord(String word, String serverId, Consumer<MBlacklist> success) {
ThreadManager.executor.submit(() -> {
ThreadManager.getExecutor("db-action").submit(() -> {
MBlacklist blacklisted = null; MBlacklist blacklisted = null;
if (isAlreadyBlacklisted(word, serverId)) { if (isAlreadyBlacklisted(word, serverId)) {
@@ -22,7 +22,7 @@ import java.util.function.Consumer;
public class DBLogging extends AbstractController { public class DBLogging extends AbstractController {
public void logGuild(Guild g) { public void logGuild(Guild g) {
ThreadManager.executor.submit(() -> { ThreadManager.getExecutor("db-action").submit(() -> {
if (!database.exists("guilds", "guild_id", g.getId())) { if (!database.exists("guilds", "guild_id", g.getId())) {
database.insert("INSERT INTO guilds VALUES(?, ?, ?)", g.getId(), g.getName(), g.getOwner().getUser().getName()); database.insert("INSERT INTO guilds VALUES(?, ?, ?)", g.getId(), g.getName(), g.getOwner().getUser().getName());
} }
@@ -30,7 +30,8 @@ public class DBLogging extends AbstractController {
} }
public void getLoggingChannel(String serverId, Consumer<TextChannel> success) { public void getLoggingChannel(String serverId, Consumer<TextChannel> success) {
ThreadManager.executor.submit(() -> {
ThreadManager.getExecutor("db-action").submit(() -> {
TextChannel txt = null; TextChannel txt = null;
ResultSet rs = database.prepareAndExecute("SELECT channelId FROM logging WHERE serverId = ?", serverId); ResultSet rs = database.prepareAndExecute("SELECT channelId FROM logging WHERE serverId = ?", serverId);
@@ -7,8 +7,10 @@ import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
//TODO: To be replaced by HTTP API actions
public class ConsoleHandler { public class ConsoleHandler {
private final static Logger logger = LoggerFactory.getLogger(ConsoleHandler.class); private final static Logger logger = LoggerFactory.getLogger(ConsoleHandler.class);
public ConsoleHandler() { public ConsoleHandler() {
logger.info("Console input ready!"); logger.info("Console input ready!");
@@ -15,28 +15,18 @@ import java.io.OutputStream;
public class ActionHandler implements HttpHandler { public class ActionHandler implements HttpHandler {
@Override @Override
public void handle(HttpExchange exchange) { public void handle(HttpExchange exchange) throws IOException {
try { String path = exchange.getRequestURI().getRawPath();
String path = exchange.getRequestURI().getRawPath();
if (path.equals("/actions/shutdown")) { if (path.equals("/actions/shutdown")) {
LogManager.getLogger().info("Request to shutdown received"); LogManager.getLogger(MusicBot.class).info("Request to shutdown received");
exchange.sendResponseHeaders(200, "Shutting down..".length()); WebApi.sendStringResponse(exchange, "Shutting down..");
OutputStream os = exchange.getResponseBody(); MusicBot.shutdown();
os.write("Shutting down..".getBytes()); return;
os.close();
//MusicBot.shutdown();
return;
}
exchange.sendResponseHeaders(200, path.length());
OutputStream os = exchange.getResponseBody();
os.write(path.getBytes());
os.close();
} catch (Exception ex) {
ex.printStackTrace();
} }
WebApi.sendStringResponse(exchange, path);
} }
} }
@@ -6,13 +6,14 @@ package netneutrality.http.server;
* This file is closed-source. It should not be distributed or copied in any way or form * This file is closed-source. It should not be distributed or copied in any way or form
*/ */
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpServer;
import netneutrality.ThreadManager;
import netneutrality.thread.BaseThread; import netneutrality.thread.BaseThread;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@@ -44,6 +45,13 @@ public class WebApi {
} }
public static void sendStringResponse(HttpExchange exchange, String str) throws IOException {
exchange.sendResponseHeaders(200, str.length());
OutputStream os = exchange.getResponseBody();
os.write(str.getBytes());
os.close();
}
} }
@@ -26,6 +26,7 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class MusicManager { public class MusicManager {
@@ -35,12 +36,11 @@ public class MusicManager {
private final AudioPlayer player; private final AudioPlayer player;
private final TrackScheduler scheduler; private final TrackScheduler scheduler;
private final static Map<String, MusicManager> managers = new ConcurrentHashMap<>(); private final static Map<String, MusicManager> managers = new ConcurrentHashMap<>();
private final long guildId; private final String guildId;
private String topic;
private MusicManager(Guild guild) { private MusicManager(Guild guild) {
this.guildId = guild.getIdLong(); this.guildId = guild.getId();
player = playerManager.createPlayer(); player = playerManager.createPlayer();
guild.getAudioManager().setSendingHandler(new AudioPlayerSendHandler(player)); guild.getAudioManager().setSendingHandler(new AudioPlayerSendHandler(player));
scheduler = new TrackScheduler(player); scheduler = new TrackScheduler(player);
@@ -70,7 +70,7 @@ public class MusicManager {
Guild guild = MusicBot.getJDA().getGuildById(guildId); Guild guild = MusicBot.getJDA().getGuildById(guildId);
guild.getAudioManager().openAudioConnection(vChannel); guild.getAudioManager().openAudioConnection(vChannel);
ThreadManager.scheduler.scheduleWithFixedDelay(() -> { ((ScheduledExecutorService) ThreadManager.getExecutor("music", ThreadManager.ExecutorType.SCHEDULED, 5)).scheduleWithFixedDelay(() -> {
if ((getCurrentlyPlaying() == null && scheduler.queue.isEmpty()) || vChannel.getMembers().size() == 0) if ((getCurrentlyPlaying() == null && scheduler.queue.isEmpty()) || vChannel.getMembers().size() == 0)
leave(); leave();
}, 120, 120, TimeUnit.SECONDS); }, 120, 120, TimeUnit.SECONDS);
@@ -17,7 +17,7 @@ public class ChannelFunction {
if (toDelete >= 2500) return; if (toDelete >= 2500) return;
ThreadManager.executor.submit(() -> { ThreadManager.getExecutor("bulk-delete", ThreadManager.ExecutorType.FIXED, 5).submit(() -> {
int toDeleteFinal = toDelete + 1; int toDeleteFinal = toDelete + 1;
int iteration = toDeleteFinal / 100; int iteration = toDeleteFinal / 100;