/** * This Source Code Form is subject to the terms of the Mozilla Public License, * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. * * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS * graphic logo is a trademark of OpenMRS Inc. */ package org.openmrs.scheduler.tasks; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.openmrs.scheduler.Task; import org.openmrs.scheduler.TaskDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class executes the Task.initialize method in a new thread. Extend this class if you want * your {@link #initialize(TaskDefinition)} method to run in a new thread (and hence not hold up the * "startup" processes) */ public class TaskThreadedInitializationWrapper implements Task { // Logger private Logger log = LoggerFactory.getLogger(TaskThreadedInitializationWrapper.class); private Task task; private boolean initialized = false; private final Lock lock = new ReentrantLock(); private final Condition initializedCond = lock.newCondition(); /** * Default constructor to create this wrapper * * @param task the Task to wrap around */ public TaskThreadedInitializationWrapper(Task task) { this.task = task; } /** * @see org.openmrs.scheduler.Task#execute() Executes the task defined in the task definition * but waits until the initialize method has finished */ @Override public void execute() { lock.lock(); try { while (!initialized) { initializedCond.await(); } } catch (InterruptedException e) { log.error("Task could not be initialized hence not be executed.", e); return; } finally { lock.unlock(); } task.execute(); } /** * @see org.openmrs.scheduler.Task#initialize(org.openmrs.scheduler.TaskDefinition) Initializes * the task and sets the task definition. This method is non-blocking by executing in a new * thread. */ @Override public void initialize(final TaskDefinition config) { Runnable r = new Runnable() { @Override public void run() { lock.lock(); try { task.initialize(config); initialized = true; initializedCond.signalAll(); } finally { lock.unlock(); } } }; new Thread(r).start(); } /** * @see org.openmrs.scheduler.Task#getTaskDefinition() */ @Override public TaskDefinition getTaskDefinition() { return task != null ? task.getTaskDefinition() : null; } /** * @see org.openmrs.scheduler.Task#isExecuting() */ @Override public boolean isExecuting() { return task.isExecuting(); } /** * @see org.openmrs.scheduler.Task#shutdown() */ @Override public void shutdown() { task.shutdown(); } }