Длинный опрос в минуту или один планировщик для задачи - Подход для системы уведомлений - PullRequest
0 голосов
/ 30 мая 2019

У меня есть требование, по которому я планирую несколько заданий на определенный интервал.И для каждой задачи уведомление должно быть отправлено через определенный интервал времени.У меня есть два подхода: либо написать один планировщик, который будет опрашивать каждую минуту и ​​соответственно отправлять уведомление.Или я могу запланировать инициализацию планировщика для каждой задачи.С первым методом решение довольно простое, с последующим я могу получить больший контроль над планировщиком, например, я могу установить начальную задержку для каждой задачи конкретно (что является требованием), затем остановить отдельную задачу, возобновить и т. Д.Пока я продолжаю с последним методом. Но я хотел бы знать, можно ли было бы использовать так много планировщиков в одном приложении.Или лучше использовать один планировщик с 1-минутным опросом? .В среднем у меня будет более 200 задач одновременно.Или для этого я могу зависеть от любой другой библиотеки ?

Пока мой код Sheduler , который является ExecutorService

       //Constructor
            public TaskScheduler(String taskName) {
                this.taskName = taskName;
                this.taskResult = new TaskResult();
                this.taskResult.setStartTime(getNewDate());
                scheduledExecutorService = Executors.newScheduledThreadPool(1);
//DB Operation
            }


    // To stop an individual task
                public TaskResult stop() throws InterruptedException {
                    try {
                        System.out.println("Stopping : " + this.taskName);
                        this.taskResult.setTaskName(this.taskName);
                        this.taskResult.setEndTime(new Date());
                        scheduledFuture.cancel(false);
                        scheduledExecutorService.shutdown();
//DB Operation 
                        System.out.println("Stopping : finished - " + this.taskName + " @ "+ new Date());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return this.taskResult;
                }

        //Portion to add task
            public TaskScheduler schedule(Runnable task, long initialDelay, long frequency) throws Exception{
                this.taskResult.setFrequencyInSeconds(frequency);
                scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(task, initialDelay, frequency, TimeUnit.SECONDS);
                return this;
            }

Задача поток с бизнес-логикой

        public class TaskModel implements Runnable {
            private String taskName;

            public TaskModel() {

            }

            public TaskModel(String taskName) {
                this.taskName = taskName;
            }

            @Override
            public void run() {
//     DB operations
    .
    .

1 Ответ

1 голос
/ 30 мая 2019

Лучше использовать один планировщик, но вам не нужно писать собственный планировщик для этого.Вы можете использовать один экземпляр Executors.newScheduledThreadPool(1) с некоторым количеством потоков для планирования всех ваших задач.

Подумайте о следующем коде:

class TaskScheduler {
    private ScheduledExecutorService scheduledExecutorService;

    public TaskScheduler(int threads) {
        this.scheduledExecutorService = Executors.newScheduledThreadPool(threads);
    }

    //Portion to add task
    public TaskExecutionContext schedule(String taskName, Runnable task, long initialDelay, long frequency) {
        TaskExecutionContext context = new TaskExecutionContext(taskName);
        context.getTaskResult().setFrequencyInSeconds(frequency);
        ScheduledFuture scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(task, initialDelay, frequency, TimeUnit.SECONDS);
        context.setScheduledFuture(scheduledFuture);
        return context;
    }
}

class TaskExecutionContext {
    private String taskName;
    private TaskResult taskResult;

    private ScheduledFuture scheduledFuture;

    public TaskExecutionContext(String taskName) {
        this.taskName = taskName;
        this.taskResult = new TaskResult();
        this.taskResult.setTaskName(taskName);
        this.taskResult.setStartTime(new Date());
        //DB Operation on creation
    }

    public TaskResult stop() {
        try {
            System.out.println("Stopping : " + this.taskName);
            this.taskResult.setTaskName(this.taskName);
            this.taskResult.setEndTime(new Date());
            scheduledFuture.cancel(false);
//DB Operation on stopping
            System.out.println("Stopping : finished - " + this.taskName + " @ " + new Date());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return this.taskResult;
    }

    public TaskResult getTaskResult() {
        return this.taskResult;
    }

    public void setScheduledFuture(ScheduledFuture scheduledFuture) {
        this.scheduledFuture = scheduledFuture;
    }
}

Если вам нужны дополнительные операции по планированию, созданиеи остановка задач - возможно, лучше иметь отдельный TaskExecutionContext, который будет выполнять все ваши потребности.

Создать контекст, когда вам нужно запланировать задачу, и передать ее в планировщик.

...