use of net.robinfriedli.aiode.concurrent.CommandExecutionTask in project aiode by robinfriedli.
the class CommandManager method runCommand.
/**
* Run command in a new thread, to be enqueued in the provided {@link ThreadExecutionQueue}.
*
* @param command the command to run
* @param executionQueue the target execution queue
*/
public void runCommand(Command command, ThreadExecutionQueue executionQueue) {
CommandContext context = command.getContext();
CommandExecutionTask commandExecutionTask = new CommandExecutionTask(command, executionQueue, this);
commandExecutionTask.setName("command-execution-" + context);
try {
boolean queued = !executionQueue.add(commandExecutionTask, false);
if (queued) {
MessageService messageService = Aiode.get().getMessageService();
messageService.sendError("Executing too many commands concurrently. This command will be executed after one has finished. " + "You may use the abort command to cancel queued commands and interrupt running commands.", context.getChannel());
logger.warn(String.format("Guild %s has reached the max concurrent commands limit.", context.getGuild()));
}
} catch (RateLimitException e) {
if (!e.isTimeout()) {
throw new InvalidCommandException(e.getMessage());
}
}
}
use of net.robinfriedli.aiode.concurrent.CommandExecutionTask in project aiode by robinfriedli.
the class AbortCommand method doRun.
@Override
public void doRun() {
CommandExecutionTask commandExecutionTask = getTask();
Thread abortThread = new Thread(() -> {
if (commandExecutionTask != null) {
try {
commandExecutionTask.await();
} catch (InterruptedException ignored) {
}
}
CommandExecutionQueueManager executionQueueManager = Aiode.get().getExecutionQueueManager();
GuildContext guildContext = getContext().getGuildContext();
ThreadExecutionQueue executionQueue = executionQueueManager.getForGuild(getContext().getGuild());
PooledTrackLoadingExecutor pooledTrackLoadingExecutor = guildContext.getPooledTrackLoadingExecutor();
ReplaceableTrackLoadingExecutor replaceableTrackLoadingExecutor = guildContext.getReplaceableTrackLoadingExecutor();
if (executionQueue.isIdle() && pooledTrackLoadingExecutor.isIdle() && replaceableTrackLoadingExecutor.isIdle()) {
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setDescription("No commands are currently running");
getMessageService().sendTemporary(embedBuilder, getContext().getChannel());
setFailed(true);
} else {
executionQueue.abortAll();
pooledTrackLoadingExecutor.abortAll();
replaceableTrackLoadingExecutor.abort();
sendSuccess("Sent all currently running commands an interrupt signal and cancelled queued commands.");
}
});
abortThread.setName("aiode abort thread");
abortThread.setUncaughtExceptionHandler(new LoggingUncaughtExceptionHandler());
abortThread.start();
}
use of net.robinfriedli.aiode.concurrent.CommandExecutionTask in project aiode by robinfriedli.
the class CommandMonitoringInterceptor method performChained.
@Override
public void performChained(Command command) {
CommandContext context = command.getContext();
CommandExecutionTask task = command.getTask();
if (task == null) {
return;
}
Future<?> monitoring = DaemonThreadPool.submit((LoggingRunnable) () -> {
Thread thread = Thread.currentThread();
String oldName = thread.getName();
thread.setName("command-monitoring-" + context);
CompletableFuture<Message> stillLoadingMessage = null;
CompletableFuture<Message> warningMessage = null;
try {
task.await(MESSAGE_AFTER_THRESHOLD);
if (!task.isDone()) {
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setDescription("Still loading...");
stillLoadingMessage = messageService.send(embedBuilder, context.getChannel());
task.await(LOGGER_WARNING_AFTER_THRESHOLD);
if (!task.isDone()) {
EmbedBuilder warningEmbed = new EmbedBuilder();
warningEmbed.setColor(Color.RED);
warningEmbed.setTitle("Command timeout");
warningEmbed.setDescription(String.format("Your command '%s' is taking very long to execute. " + "If the command is not responding, consider interrupting it using the abort command.", command.display()));
warningMessage = messageService.send(warningEmbed.build(), context.getChannel());
logger.warn(String.format("Command [%s] on guild %s has exceeded the warn limit for execution duration of %d millis.", command.display(), context.getGuild(), MESSAGE_AFTER_THRESHOLD + LOGGER_WARNING_AFTER_THRESHOLD));
}
task.await();
deleteMessages(stillLoadingMessage, warningMessage);
}
} catch (InterruptedException e) {
// CommandExecutionInterceptor interrupts monitoring in post command
deleteMessages(stillLoadingMessage, warningMessage);
} finally {
thread.setName(oldName);
}
});
context.registerMonitoring(monitoring);
}
Aggregations