package io.linuxserver.davos.schedule; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import javax.annotation.PostConstruct; import javax.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import io.linuxserver.davos.exception.ScheduleAlreadyRunningException; import io.linuxserver.davos.exception.ScheduleNotRunningException; import io.linuxserver.davos.persistence.dao.ScheduleDAO; import io.linuxserver.davos.persistence.model.ScheduleModel; @Component public class ScheduleExecutor { private static final Logger LOGGER = LoggerFactory.getLogger(ScheduleExecutor.class); private Map<Long, RunningSchedule> runningSchedules = new HashMap<>(); @Resource private ScheduleDAO scheduleConfigurationDAO; private ScheduledExecutorService scheduledExecutorService; public ScheduleExecutor() { this.scheduledExecutorService = Executors.newScheduledThreadPool(10); } public boolean isScheduleRunning(Long id) { return runningSchedules.containsKey(id); } public RunningSchedule getRunningSchedule(Long id) { return runningSchedules.get(id); } @PostConstruct public void runAutomaticStartupSchedules() { LOGGER.info("Initialising automatic startup schedules"); for (ScheduleModel model : scheduleConfigurationDAO.getAll()) { if (model.getStartAutomatically()) { RunnableSchedule runnable = new RunnableSchedule(model.id, scheduleConfigurationDAO); ScheduledFuture<?> runningSchedule = scheduledExecutorService.scheduleAtFixedRate(runnable, 0, model.interval, TimeUnit.MINUTES); runningSchedules.put(model.id, new RunningSchedule(runningSchedule, runnable)); } } LOGGER.info("Automatic startup schedules should now be running"); } public void startSchedule(Long id) throws ScheduleAlreadyRunningException { if (!runningSchedules.containsKey(id)) { ScheduleModel model = scheduleConfigurationDAO.fetchSchedule(id); RunnableSchedule runnable = new RunnableSchedule(model.id, scheduleConfigurationDAO); LOGGER.info("Starting schedule {}", id); ScheduledFuture<?> runningSchedule = scheduledExecutorService.scheduleAtFixedRate(runnable, 0, model.interval, TimeUnit.MINUTES); runningSchedules.put(model.id, new RunningSchedule(runningSchedule, runnable)); } else { throw new ScheduleAlreadyRunningException(); } } public void stopSchedule(Long id) throws ScheduleNotRunningException { if (runningSchedules.containsKey(id)) { LOGGER.info("Stopping schedule {}", id); ScheduledFuture<?> future = runningSchedules.get(id).getFuture(); if (!future.isCancelled()) { future.cancel(true); runningSchedules.remove(id); LOGGER.info("Schedule should now be stopped"); } } else { throw new ScheduleNotRunningException(); } } }