Updated threadmanager and refactored code
This commit is contained in:
1 parent
62fe015ffa
commit
c11af0da51
11 files changed
+103
-78
No files matched your search
@@ -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"));
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in new issue
Block a user