/** * Loop over all currently started tasks and cycle them. This should be done after the classloader * has been changed (e.g. during module start/stop) */ public void rescheduleAllTasks() throws SchedulerException { for (TaskDefinition task : getScheduledTasks()) { try { rescheduleTask(task); } catch (SchedulerException e) { log.error("Failed to restart task: " + task.getName(), e); } } }
/** * Delete the task with the given identifier. * * @param id the identifier of the task */ public void deleteTask(Integer id) { TaskDefinition task = getTask(id); if (task.getStarted()) { throw new APIException( "Started tasks should not be deleted. They should be stopped first, and then deleted."); } // delete the task getSchedulerDAO().deleteTask(id); }
/** * Get all scheduled tasks. * * @return all scheduled tasks */ public Collection<TaskDefinition> getScheduledTasks() { // The real list of scheduled tasks is kept up-to-date in the scheduledTasks map // TODO change the index for the scheduledTasks map to be the TaskDefinition rather than the ID List<TaskDefinition> list = new ArrayList<TaskDefinition>(); Set<Integer> taskIds = scheduledTasks.keySet(); for (Integer id : taskIds) { TaskDefinition task = getTask(id); log.debug("Adding scheduled task " + id + " to list (" + task.getRepeatInterval() + ")"); list.add(task); } return list; }
/** * Stops a running task. * * @param taskDefinition the task to be stopped * @see org.openmrs.scheduler.SchedulerService#shutdownTask(TaskDefinition) */ public void shutdownTask(TaskDefinition taskDefinition) throws SchedulerException { if (taskDefinition != null) { // Remove the task from the scheduled tasks and shutdown the timer TimerSchedulerTask schedulerTask = scheduledTasks.remove(taskDefinition.getId()); if (schedulerTask != null) { schedulerTask .shutdown(); // Stops the timer and tells the timer task to release its resources } // Update task that has been started taskDefinition.setStarted(false); saveTask(taskDefinition); } }
/** Shutdown all running tasks. */ public void shutdownAllTasks() { // iterate over this (copied) list of tasks and stop them all for (TaskDefinition task : getScheduledTasks()) { try { shutdownTask(task); } catch (SchedulerException e) { log.error("Failed to stop task " + task.getTaskClass() + " due to Scheduler exception", e); } catch (APIException e) { log.error("Failed to stop task " + task.getTaskClass() + " due to API exception", e); } } }
/** * Save a task in the database. * * @param task the <code>TaskDefinition</code> to save */ public void saveTaskDefinition(TaskDefinition task) { if (task.getId() != null) { getSchedulerDAO().updateTask(task); } else { getSchedulerDAO().createTask(task); } }
/** * Saves and stops all active tasks * * @return OpenmrsMemento */ public OpenmrsMemento saveToMemento() { Set<Integer> tasks = new HashSet<Integer>(); for (TaskDefinition task : getScheduledTasks()) { tasks.add(task.getId()); try { shutdownTask(task); } catch (SchedulerException e) { // just swallow exceptions log.debug("Failed to stop task while saving memento " + task.getName(), e); } } TimerSchedulerMemento memento = new TimerSchedulerMemento(tasks); memento.saveErrorTasks(); return memento; }
/** Start up hook for the scheduler and all of its scheduled tasks. */ public void onStartup() { log.debug("Starting scheduler service ..."); // Get all of the tasks in the database Collection<TaskDefinition> taskDefinitions = getSchedulerDAO().getTasks(); // Iterate through the tasks and start them if their startOnStartup flag is true if (taskDefinitions != null) { for (TaskDefinition taskDefinition : taskDefinitions) { try { // If the task is configured to start on startup, we schedule it to run // Otherwise it needs to be started manually. if (taskDefinition.getStartOnStartup()) { scheduleTask(taskDefinition); } } catch (Exception e) { log.error("Failed to schedule task for class " + taskDefinition.getTaskClass(), e); } } } }
@Override public void scheduleIfNotRunning(TaskDefinition taskDef) { Task task = taskDef.getTaskInstance(); if (task == null) { try { scheduleTask(taskDef); } catch (SchedulerException e) { log.error("Failed to schedule task, because:", e); } } else if (!task.isExecuting()) { try { rescheduleTask(taskDef); } catch (SchedulerException e) { log.error("Failed to re-schedule task, because:", e); } } }
/** * Tests whether the TimerScheduler schedules tasks even if the repeatInterval is zero. * * @see {@link TimerSchedulerServiceImpl#scheduleTask(TaskDefinition)} */ @Test @Verifies(value = "should handle zero repeat interval", method = "scheduleTask(TaskDefinition)") public void scheduleTask_shouldHandleZeroRepeatInterval() throws Exception { // Represents the start time of the task (right now) Calendar startTime = Calendar.getInstance(); // Define repeatInterval as zero Long repeatInterval = new Long(0); String taskName = "TestTask"; String className = "org.openmrs.scheduler.tasks.TestTask"; Boolean startOnStartup = false; // Create the new task TaskDefinition taskDefinition = new TaskDefinition(); taskDefinition.setName(taskName); taskDefinition.setTaskClass(className); taskDefinition.setStartTime(startTime.getTime()); taskDefinition.setRepeatInterval(repeatInterval); taskDefinition.setStartOnStartup(startOnStartup); Task clientTask = null; TimerSchedulerServiceImpl t = new TimerSchedulerServiceImpl(); clientTask = t.scheduleTask(taskDefinition); // without this commit there seems to be a table lock left on the SCHEDULER_TASK_CONFIG table, // see TRUNK-4212 Context.flushSession(); getConnection().commit(); // Assert that the clientTask is not null, i.e. the sheduleTask was able to successfully // schedule in case of zero repeatInterval. assertNotNull( "The clientTask variable is null, so either the TimerSchedulerServiceImpl.scheduleTask method hasn't finished or didn't get run", clientTask); }
/** * Schedule the given task according to the given schedule. * * @param taskDefinition the task to be scheduled * @should should handle zero repeat interval */ public Task scheduleTask(TaskDefinition taskDefinition) throws SchedulerException { Task clientTask = null; if (taskDefinition != null) { // Cancel any existing timer tasks for the same task definition // TODO Make sure this is the desired behavior // TODO Do we ever want the same task definition to run more than once? TimerSchedulerTask schedulerTask = scheduledTasks.get(taskDefinition.getId()); if (schedulerTask != null) { // schedulerTask.cancel(); log.info("Shutting down the existing instance of this task to avoid conflicts!!"); schedulerTask.shutdown(); } try { // Create new task from task definition clientTask = TaskFactory.getInstance().createInstance(taskDefinition); // if we were unable to get a class, just quit if (clientTask != null) { schedulerTask = new TimerSchedulerTask(clientTask); taskDefinition.setTaskInstance(clientTask); // Once this method is called, the timer is set to start at the given start time. // NOTE: We need to adjust the repeat interval as the JDK Timer expects time in // milliseconds and // we record by seconds. long repeatInterval = 0; if (taskDefinition.getRepeatInterval() != null) repeatInterval = taskDefinition.getRepeatInterval() * SchedulerConstants.SCHEDULER_MILLIS_PER_SECOND; if (taskDefinition.getStartTime() != null) { // Need to calculate the "next execution time" because the scheduled time is most likely // in the past // and the JDK timer will run the task X number of times from the start time until now // to catch up. Date nextTime = SchedulerUtil.getNextExecution(taskDefinition); // Start task at fixed rate at given future date and repeat as directed log.info("Starting task ... the task will execute for the first time at " + nextTime); if (repeatInterval > 0) { // Schedule the task to run at a fixed rate getTimer(taskDefinition).scheduleAtFixedRate(schedulerTask, nextTime, repeatInterval); } else { // Schedule the task to be non-repeating getTimer(taskDefinition).schedule(schedulerTask, nextTime); } } else if (repeatInterval > 0) { // Start task on repeating schedule, delay for SCHEDULER_DEFAULT_DELAY seconds log.info( "Delaying start time by " + SchedulerConstants.SCHEDULER_DEFAULT_DELAY + " seconds"); getTimer(taskDefinition) .scheduleAtFixedRate( schedulerTask, SchedulerConstants.SCHEDULER_DEFAULT_DELAY, repeatInterval); } else { // schedule for single execution, starting now log.info("Starting one-shot task"); getTimer(taskDefinition).schedule(schedulerTask, new Date()); } // Update task that has been started log.debug("Registering timer for task " + taskDefinition.getId()); // Add the new timer to the scheduler running task list scheduledTasks.put(taskDefinition.getId(), schedulerTask); // Update the timer status in the database taskDefinition.setStarted(true); saveTask(taskDefinition); } } catch (Exception e) { log.error("Failed to schedule task " + taskDefinition.getName(), e); throw new SchedulerException("Failed to schedule task", e); } } return clientTask; }