/** * The contents of this file are subject to the OpenMRS Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ 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.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.scheduler.Task; import org.openmrs.scheduler.TaskDefinition; /** * 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 Log log = LogFactory.getLog(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; } /** * @throws InterruptedException * @see org.openmrs.scheduler.Task#execute() Executes the task defined in the task definition * but waits until the initialize method has finished */ 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. */ public void initialize(final TaskDefinition config) { Runnable r = new Runnable() { 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() */ public TaskDefinition getTaskDefinition() { return task != null ? task.getTaskDefinition() : null; } /** * @see org.openmrs.scheduler.Task#isExecuting() */ public boolean isExecuting() { return task.isExecuting(); } /** * @see org.openmrs.scheduler.Task#shutdown() */ public void shutdown() { task.shutdown(); } }