From 1d737a2a4f64f61894f763d69557b6c93ab17018 Mon Sep 17 00:00:00 2001 From: anthorob Date: Wed, 9 Sep 2026 15:10:33 -0400 Subject: [PATCH] Migrate scheduled tasks to a new package and architecture Refactored scheduled tasks and moved them to a dedicated `scheduled` package. Replaced the legacy `ScheduledTaskManager` and `ScheduledTask` definitions with a redesigned architecture to improve maintainability. Updated related classes and configurations to adopt the new structure. --- pom.xml | 2 +- .../java/me/bobert/netneutrality/App.java | 8 ++--- .../{tasks => scheduled}/ScheduledTask.java | 2 +- .../ScheduledTaskManager.java | 33 ++++++++++++++++--- .../netneutrality/core/tasks/TaskManager.java | 2 +- .../core/tasks/TaskManagerImpl.java | 24 -------------- .../cleanup}/TaskCleanup.java | 9 +++-- .../music/MusicManagerCleanup.java | 4 +-- .../music/MusicPlayerAutoDisconnect.java | 4 +-- 9 files changed, 46 insertions(+), 42 deletions(-) rename src/main/java/me/bobert/netneutrality/core/{tasks => scheduled}/ScheduledTask.java (96%) rename src/main/java/me/bobert/netneutrality/core/{thread => scheduled}/ScheduledTaskManager.java (67%) rename src/main/java/me/bobert/netneutrality/{core/tasks => scheduled/cleanup}/TaskCleanup.java (79%) rename src/main/java/me/bobert/netneutrality/{tasks => scheduled}/music/MusicManagerCleanup.java (93%) rename src/main/java/me/bobert/netneutrality/{tasks => scheduled}/music/MusicPlayerAutoDisconnect.java (96%) diff --git a/pom.xml b/pom.xml index 423a07a..e325414 100644 --- a/pom.xml +++ b/pom.xml @@ -149,7 +149,7 @@ dev.arbjerg lavaplayer - 2.2.6 + 2.2.7 dev.lavalink.youtube diff --git a/src/main/java/me/bobert/netneutrality/App.java b/src/main/java/me/bobert/netneutrality/App.java index 36487a4..6ef5d3c 100644 --- a/src/main/java/me/bobert/netneutrality/App.java +++ b/src/main/java/me/bobert/netneutrality/App.java @@ -16,7 +16,7 @@ import me.bobert.netneutrality.core.LogHandler; import me.bobert.netneutrality.core.command.CommandManager; import me.bobert.netneutrality.db.SessionManager; import me.bobert.netneutrality.core.tasks.TaskManagerImpl; -import me.bobert.netneutrality.core.thread.ScheduledTaskManager; +import me.bobert.netneutrality.core.scheduled.ScheduledTaskManager; import me.bobert.netneutrality.core.thread.ThreadManager; import me.bobert.netneutrality.db.service.GuildServiceProviderImpl; import me.bobert.netneutrality.music.MusicService; @@ -125,9 +125,9 @@ public class App { ExecutorProvider executors = context.register(new ThreadManager()); ChannelMessagePurger.bind(executors); - // Scheduled tasks (priority 55): constructed early so TaskManager can resolve it; cancelled - // early on shutdown, before executors. - context.register(new ScheduledTaskManager(executors)); + // Scheduled tasks (priority 55): discovers and schedules all ScheduledTask implementations + // on start; cancelled early on shutdown, before executors. + context.register(new ScheduledTaskManager(executors, context)); // Command registry (priority 30). CommandRegistry commands = context.register(new CommandManager(context)); diff --git a/src/main/java/me/bobert/netneutrality/core/tasks/ScheduledTask.java b/src/main/java/me/bobert/netneutrality/core/scheduled/ScheduledTask.java similarity index 96% rename from src/main/java/me/bobert/netneutrality/core/tasks/ScheduledTask.java rename to src/main/java/me/bobert/netneutrality/core/scheduled/ScheduledTask.java index d7a3c3e..aa9a374 100644 --- a/src/main/java/me/bobert/netneutrality/core/tasks/ScheduledTask.java +++ b/src/main/java/me/bobert/netneutrality/core/scheduled/ScheduledTask.java @@ -1,4 +1,4 @@ -package me.bobert.netneutrality.core.tasks; +package me.bobert.netneutrality.core.scheduled; /* * Copyright (c) anthorob diff --git a/src/main/java/me/bobert/netneutrality/core/thread/ScheduledTaskManager.java b/src/main/java/me/bobert/netneutrality/core/scheduled/ScheduledTaskManager.java similarity index 67% rename from src/main/java/me/bobert/netneutrality/core/thread/ScheduledTaskManager.java rename to src/main/java/me/bobert/netneutrality/core/scheduled/ScheduledTaskManager.java index 7d4f403..e903c6c 100644 --- a/src/main/java/me/bobert/netneutrality/core/thread/ScheduledTaskManager.java +++ b/src/main/java/me/bobert/netneutrality/core/scheduled/ScheduledTaskManager.java @@ -1,4 +1,4 @@ -package me.bobert.netneutrality.core.thread; +package me.bobert.netneutrality.core.scheduled; /* * Copyright (c) anthorob @@ -6,9 +6,11 @@ package me.bobert.netneutrality.core.thread; * https://discord.gg/qUa6zNFZsd */ +import me.bobert.netneutrality.bootstrap.ApplicationContext; import me.bobert.netneutrality.bootstrap.Lifecycle; +import me.bobert.netneutrality.bootstrap.ReflectionHelper; import me.bobert.netneutrality.core.LogHandler; -import me.bobert.netneutrality.core.tasks.ScheduledTask; +import me.bobert.netneutrality.core.thread.ExecutorProvider; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -16,18 +18,24 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; +import java.util.function.Consumer; /** * Instance-based {@link Lifecycle} component that owns scheduled fixed-delay tasks. + * + *

On {@link #start()} it discovers all concrete {@link ScheduledTask} implementations via + * reflection and schedules them automatically. */ public class ScheduledTaskManager implements Lifecycle { private static final Logger logger = LogManager.getLogger(ScheduledTaskManager.class); private final Map> scheduledTasks = new ConcurrentHashMap<>(); private final ScheduledExecutorService executorService; + private final ApplicationContext context; - public ScheduledTaskManager(ExecutorProvider executors) { + public ScheduledTaskManager(ExecutorProvider executors, ApplicationContext context) { this.executorService = executors.getScheduledExecutor(); + this.context = context; } @Override @@ -38,7 +46,7 @@ public class ScheduledTaskManager implements Lifecycle { @Override public void start() { - // Tasks are scheduled by TaskManagerImpl during its own start; nothing to eagerly start. + loadScheduledTasks(); } @Override @@ -84,4 +92,21 @@ public class ScheduledTaskManager implements Lifecycle { scheduledTasks.forEach((id, future) -> future.cancel(false)); scheduledTasks.clear(); } + + private void loadScheduledTasks() { + logger.info("Loading scheduled tasks..."); + + Consumer onLoaded = scheduledTask -> { + String taskId = scheduledTask.getId(); + + if (taskId == null || taskId.trim().isEmpty()) { + logger.error("Cannot load scheduled task {}: task ID is null or empty", scheduledTask.getClass().getName()); + return; + } + + schedule(scheduledTask); + }; + + ReflectionHelper.loadTasks(ScheduledTask.class, context, onLoaded); + } } diff --git a/src/main/java/me/bobert/netneutrality/core/tasks/TaskManager.java b/src/main/java/me/bobert/netneutrality/core/tasks/TaskManager.java index 6a90076..52bff08 100644 --- a/src/main/java/me/bobert/netneutrality/core/tasks/TaskManager.java +++ b/src/main/java/me/bobert/netneutrality/core/tasks/TaskManager.java @@ -18,7 +18,7 @@ import me.bobert.netneutrality.db.service.TaskService; /** * Owns the in-memory task registry, button/interaction dispatch, and persistable-task loading. * - *

As a {@link Lifecycle} component it loads built-in, scheduled and persisted tasks on + *

As a {@link Lifecycle} component it loads built-in and persisted tasks on * {@link #start()}. */ public interface TaskManager extends Lifecycle { diff --git a/src/main/java/me/bobert/netneutrality/core/tasks/TaskManagerImpl.java b/src/main/java/me/bobert/netneutrality/core/tasks/TaskManagerImpl.java index 8175522..c6171b0 100644 --- a/src/main/java/me/bobert/netneutrality/core/tasks/TaskManagerImpl.java +++ b/src/main/java/me/bobert/netneutrality/core/tasks/TaskManagerImpl.java @@ -15,7 +15,6 @@ import me.bobert.netneutrality.core.tasks.trait.NotAcknowledgeable; import me.bobert.netneutrality.core.tasks.trait.WithButton; import me.bobert.netneutrality.core.tasks.trait.WithChildren; import me.bobert.netneutrality.core.tasks.trait.WithParent; -import me.bobert.netneutrality.core.thread.ScheduledTaskManager; import me.bobert.netneutrality.db.service.TaskService; import me.bobert.netneutrality.exceptions.GracefulContextError; import me.bobert.netneutrality.exceptions.TaskExecutionException; @@ -77,7 +76,6 @@ public class TaskManagerImpl implements TaskManager { logger.info("Initializing task manager..."); loadBuiltInTasks(); - loadScheduledTasks(); taskService.loadTasks(); } @@ -272,28 +270,6 @@ public class TaskManagerImpl implements TaskManager { ReflectionHelper.loadTasks(BuiltInTask.class, context, onLoaded); } - private void loadScheduledTasks() { - logger.info("Loading scheduled tasks..."); - - ScheduledTaskManager scheduledTaskManager = context.get(ScheduledTaskManager.class); - if (scheduledTaskManager == null) { - logger.error("ScheduledTaskManager is not available; cannot load scheduled tasks"); - return; - } - - Consumer onLoaded = scheduledTask -> { - String taskId = scheduledTask.getId(); - - if (taskId == null || taskId.trim().isEmpty()) { - logger.error("Cannot load scheduled task {}: task ID is null or empty", scheduledTask.getClass().getName()); - return; - } - - scheduledTaskManager.schedule(scheduledTask); - }; - - ReflectionHelper.loadTasks(ScheduledTask.class, context, onLoaded); - } private void deleteInteraction(Task task) { if (task instanceof WithParent taskWithParent) { diff --git a/src/main/java/me/bobert/netneutrality/core/tasks/TaskCleanup.java b/src/main/java/me/bobert/netneutrality/scheduled/cleanup/TaskCleanup.java similarity index 79% rename from src/main/java/me/bobert/netneutrality/core/tasks/TaskCleanup.java rename to src/main/java/me/bobert/netneutrality/scheduled/cleanup/TaskCleanup.java index 1bd962f..71e76b2 100644 --- a/src/main/java/me/bobert/netneutrality/core/tasks/TaskCleanup.java +++ b/src/main/java/me/bobert/netneutrality/scheduled/cleanup/TaskCleanup.java @@ -1,10 +1,15 @@ -package me.bobert.netneutrality.core.tasks; +package me.bobert.netneutrality.scheduled.cleanup; /* * Copyright (c) anthorob * * https://discord.gg/qUa6zNFZsd */ +import me.bobert.netneutrality.core.scheduled.ScheduledTask; +import me.bobert.netneutrality.core.tasks.BuiltInTask; +import me.bobert.netneutrality.core.tasks.PersistableTask; +import me.bobert.netneutrality.core.tasks.Task; +import me.bobert.netneutrality.core.tasks.TaskManager; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -13,8 +18,6 @@ import java.util.Objects; /** * Periodically removes expired in-memory tasks. - * - *

Scheduled task migrated to constructor injection of {@link TaskManager}. */ public class TaskCleanup implements ScheduledTask { private static final Logger logger = LogManager.getLogger(TaskCleanup.class); diff --git a/src/main/java/me/bobert/netneutrality/tasks/music/MusicManagerCleanup.java b/src/main/java/me/bobert/netneutrality/scheduled/music/MusicManagerCleanup.java similarity index 93% rename from src/main/java/me/bobert/netneutrality/tasks/music/MusicManagerCleanup.java rename to src/main/java/me/bobert/netneutrality/scheduled/music/MusicManagerCleanup.java index d1c6a44..a177d4e 100644 --- a/src/main/java/me/bobert/netneutrality/tasks/music/MusicManagerCleanup.java +++ b/src/main/java/me/bobert/netneutrality/scheduled/music/MusicManagerCleanup.java @@ -1,11 +1,11 @@ -package me.bobert.netneutrality.tasks.music; +package me.bobert.netneutrality.scheduled.music; /* * Copyright (c) anthorob * * https://discord.gg/qUa6zNFZsd */ -import me.bobert.netneutrality.core.tasks.ScheduledTask; +import me.bobert.netneutrality.core.scheduled.ScheduledTask; import me.bobert.netneutrality.music.MusicManager; import me.bobert.netneutrality.music.TrackScheduler; import org.apache.logging.log4j.LogManager; diff --git a/src/main/java/me/bobert/netneutrality/tasks/music/MusicPlayerAutoDisconnect.java b/src/main/java/me/bobert/netneutrality/scheduled/music/MusicPlayerAutoDisconnect.java similarity index 96% rename from src/main/java/me/bobert/netneutrality/tasks/music/MusicPlayerAutoDisconnect.java rename to src/main/java/me/bobert/netneutrality/scheduled/music/MusicPlayerAutoDisconnect.java index e0656bf..b624fbc 100644 --- a/src/main/java/me/bobert/netneutrality/tasks/music/MusicPlayerAutoDisconnect.java +++ b/src/main/java/me/bobert/netneutrality/scheduled/music/MusicPlayerAutoDisconnect.java @@ -1,4 +1,4 @@ -package me.bobert.netneutrality.tasks.music; +package me.bobert.netneutrality.scheduled.music; /* * Copyright (c) anthorob @@ -6,7 +6,7 @@ package me.bobert.netneutrality.tasks.music; * https://discord.gg/qUa6zNFZsd */ -import me.bobert.netneutrality.core.tasks.ScheduledTask; +import me.bobert.netneutrality.core.scheduled.ScheduledTask; import me.bobert.netneutrality.music.MusicManager; import me.bobert.netneutrality.music.MusicService; import net.dv8tion.jda.api.entities.Member;