/** * This method should be called after restoring the instance * * @see #destroyInstance() * @see #saveState() */ public static void restoreState() { try { String key = SchedulerService.class.getName(); Context.getSchedulerService().restoreFromMemento(mementos.get(key)); } catch (APIException e) { // pass } mementos.clear(); }
/** * All objects depending on the old classloader should be restarted here Should be called after * destoryInstance() and after the service is restarted * * @see #destroyInstance() */ public static void flushInstance() { try { SchedulerService service = null; try { service = Context.getSchedulerService(); } catch (APIException e2) { // if there isn't a scheduler service yet, ignore error log.warn("Unable to get scheduler service", e2); } if (service != null) { service.rescheduleAllTasks(); } } catch (SchedulerException e) { log.error("Failed to restart scheduler tasks", e); } }
/** * This method should be called before destroying the instance * * @see #destroyInstance() */ public static void saveState() { try { String key = SchedulerService.class.getName(); if (!Context.isRefreshingContext()) { mementos.put(key, Context.getSchedulerService().saveToMemento()); } } catch (Exception t) { // pass } }
/** * Start the scheduler given the following start up properties. * * @param p properties used to start the service */ public static void startup(Properties p) { // Override the Scheduler constants if specified by the user String val = p.getProperty("scheduler.username", null); if (val != null) { SchedulerConstants.SCHEDULER_DEFAULT_USERNAME = val; log.warn("Deprecated runtime property: scheduler.username. Value set in global_property in database now."); } val = p.getProperty("scheduler.password", null); if (val != null) { SchedulerConstants.SCHEDULER_DEFAULT_PASSWORD = val; log.warn("Deprecated runtime property: scheduler.username. Value set in global_property in database now."); } // TODO: do this for all services try { Context.addProxyPrivilege(PrivilegeConstants.MANAGE_SCHEDULER); Context.getSchedulerService().onStartup(); } finally { Context.removeProxyPrivilege(PrivilegeConstants.MANAGE_SCHEDULER); } }
/** * Save the last execution time in the TaskDefinition */ private static void saveLastExecutionTime(Task task) { TaskDefinition taskDefinition; try { // We re-get the task definition in case the copy set during the // task initialization has become stale. NOTE: If a task does not // extend the abstract class AbstractTask, then it's possible the // developer did not actually set the TaskDefintion on the Task. // Therefore we might get an NPE below. if (task.getTaskDefinition() != null) { SchedulerService schedulerService = Context.getSchedulerService(); taskDefinition = task.getTaskDefinition(); taskDefinition.setLastExecutionTime(new Date()); schedulerService.saveTaskDefinition(taskDefinition); } else { log.warn("Unable to save the last execution time for task. Task.taskDefinition is null in " + task.getClass()); } } catch (Exception e) { log.warn("Unable to save the last execution time for task ", e); } }
/** * Shutdown the scheduler service that is statically associated with the Context class. */ public static void shutdown() { SchedulerService service = null; // ignores errors while getting the scheduler service try { service = Context.getSchedulerService(); } catch (Exception e) { // pass } // TODO: Do this for all services try { Context.addProxyPrivilege(PrivilegeConstants.MANAGE_SCHEDULER); // doesn't attempt shutdown if there was an error getting the scheduler service if (service != null) { service.onShutdown(); } } finally { Context.removeProxyPrivilege(PrivilegeConstants.MANAGE_SCHEDULER); } }
/** Stops all tasks started by given module * @param mod */ private static void stopTasks(Module mod) { SchedulerService schedulerService = Context.getSchedulerService(); String modulePackageName = mod.getPackageName(); for (TaskDefinition task : schedulerService.getRegisteredTasks()) { String taskClass = task.getTaskClass(); if (isModulePackageNameInTaskClass(modulePackageName, taskClass)) { try { schedulerService.shutdownTask(task); } catch (SchedulerException e) { log.error("Couldn't stop task:" + task + " for module: " + mod); } } } }
@Before public void setUp() throws Exception { // Temporary logger level changes to debug TRUNK-4212 LogManager.getLogger("org.hibernate.SQL").setLevel(Level.DEBUG); LogManager.getLogger("org.hibernate.type").setLevel(Level.TRACE); LogManager.getLogger("org.openmrs.api").setLevel(Level.DEBUG); LogManager.getLogger("org.openmrs.scheduler").setLevel(Level.DEBUG); log.debug("SchedulerServiceTest setup() start"); Context.flushSession(); Collection<TaskDefinition> tasks = Context.getSchedulerService().getRegisteredTasks(); for (TaskDefinition task : tasks) { Context.getSchedulerService().shutdownTask(task); Context.getSchedulerService().deleteTask(task.getId()); } Context.flushSession(); log.debug("SchedulerServiceTest setup() complete"); }
private void checkTasksRunConcurrently(TaskDefinition t1, TaskDefinition t2) throws SchedulerException, InterruptedException { SchedulerService schedulerService = Context.getSchedulerService(); // synchronized on a class level object in case a test runner is running test methods concurrently synchronized (TASK_TEST_METHOD_LOCK) { latch = new CountDownLatch(2); awaitFailed.set(false); schedulerService.scheduleTask(t1); schedulerService.scheduleTask(t2); // wait for the tasks to call countDown() assertTrue("methods ran consecutively or not at all", latch .await(CONCURRENT_TASK_WAIT_MS, TimeUnit.MILLISECONDS)); // the main await() didn't fail so both tasks ran and called countDown(), // but if the first await() failed and the latch still reached 0 then the tasks must have been running consecutively assertTrue("methods ran consecutively", !awaitFailed.get()); } schedulerService.shutdownTask(t1); schedulerService.shutdownTask(t2); }
/** * Demonstrates that initialization of a task is accomplished before its execution without * interleaving, which is a non-trivial behavior in the presence of a threaded initialization * method (as implemented in TaskThreadedInitializationWrapper) */ @Test public void shouldNotAllowTaskExecuteToRunBeforeInitializationIsComplete() throws Exception { SchedulerService schedulerService = Context.getSchedulerService(); TaskDefinition t5 = new TaskDefinition(); t5.setStartOnStartup(false); t5.setStartTime(null); // immediate start t5.setTaskClass(InitSequenceTestTask.class.getName()); t5.setName("name"); t5.setRepeatInterval(CONCURRENT_TASK_WAIT_MS * 4); synchronized (TASK_TEST_METHOD_LOCK) { // wait for the task to complete latch = new CountDownLatch(1); consecutiveInitResult.set(false); schedulerService.saveTaskDefinition(t5); schedulerService.scheduleTask(t5); assertTrue("Init and execute methods should run consecutively", latch.await(CONCURRENT_TASK_WAIT_MS, TimeUnit.MILLISECONDS) && consecutiveInitResult.get()); } schedulerService.shutdownTask(t5); }
@Test public void saveTask_shouldSaveTaskToTheDatabase() throws Exception { log.debug("saveTask_shouldSaveTaskToTheDatabase start"); SchedulerService service = Context.getSchedulerService();
private TaskDefinition makeRepeatingTaskThatStartsImmediately(String taskClassName) { TaskDefinition taskDef = new TaskDefinition(); taskDef.setTaskClass(taskClassName); taskDef.setStartOnStartup(false); taskDef.setStartTime(null); taskDef.setName("name"); taskDef.setRepeatInterval(CONCURRENT_TASK_WAIT_MS * 10); // latch should timeout before task ever repeats // save task definition to generate a unique ID, otherwise the scheduler thinks they're duplicates and tries to shut one down Context.getSchedulerService().saveTaskDefinition(taskDef); return taskDef; }
/** * Task which does not return TaskDefinition in getTaskDefinition should run without throwing * exceptions. * * @throws Exception */ @Test public void shouldNotThrowExceptionWhenTaskDefinitionIsNull() throws Exception { SchedulerService schedulerService = Context.getSchedulerService(); TaskDefinition td = new TaskDefinition(); td.setName("Task"); td.setStartOnStartup(false); td.setTaskClass(BareTask.class.getName()); td.setStartTime(null); td.setName("name"); td.setRepeatInterval(5000L); synchronized (TASK_TEST_METHOD_LOCK) { latch = new CountDownLatch(1); schedulerService.saveTaskDefinition(td); schedulerService.scheduleTask(td); assertTrue(latch.await(CONCURRENT_TASK_WAIT_MS, TimeUnit.MILLISECONDS)); } }
log.debug("shouldSaveLastExecutionTime start"); final String NAME = "StoreExecutionTime Task"; SchedulerService service = Context.getSchedulerService();
clientTask = Context.getSchedulerService().scheduleTask(taskDefinition);
/** * Save the new task in the service * * @param task will contain the taskDefinition to be saved */ public void saveTaskDefinition(TaskDefinition task) { Context.getSchedulerService().saveTaskDefinition(task); }
/** * It will shutdown a task which is scheduled in the service * * @param task contains the taskDefinition to be shutdown * @throws SchedulerException - It will throw in case of any SchedulerService exceptions */ public void shutDownTask(TaskDefinition task) throws SchedulerException { Context.getSchedulerService().shutdownTask(task); }
/** * It will re-schedule a task which is registered in the service * * @param task contains the taskDefinition to be re-scheduled * @throws SchedulerException - It will throw in case of any SchedulerService exceptions */ public void reScheduleTask(TaskDefinition task) throws SchedulerException { Context.getSchedulerService().rescheduleTask(task); }
/** * It will re-schedule all the tasks which are registered in the service * * @throws SchedulerException - It will throw in case of any SchedulerService exceptions */ public void reScheduleAllTasks() throws SchedulerException { Context.getSchedulerService().rescheduleAllTasks(); }
/** * It will delete the task from the service * * @param task will contain the taskDefinition to be deleted * @throws SchedulerException - It will throw in case of any SchedulerService exceptions */ public void deleteTask(TaskDefinition task) throws SchedulerException { Context.getSchedulerService().deleteTask(task.getId()); }