/*
* Copyright(c) 2005 Center for E-Commerce Infrastructure Development, The
* University of Hong Kong (HKU). All Rights Reserved.
*
* This software is licensed under the GNU GENERAL PUBLIC LICENSE Version 2.0 [1]
*
* [1] http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*/
package hk.hku.cecid.piazza.commons.module;
import hk.hku.cecid.piazza.commons.util.StringUtilities;
import java.util.Iterator;
import java.util.Properties;
/**
* ActiveTaskModule is an active module which manages an active task list. As
* an active module, it runs as a separated thread and loops through the task
* list for executing the tasks. It also contains an active monitor responsible
* for monitoring and controlling the thread count.
*
* @author Hugo Y. K. Lam
*
*/
public class ActiveTaskModule extends ActiveModule {
private ActiveMonitor monitor = new ActiveMonitor();
private ActiveTaskList taskList;
private int maxThreadCount = 1;
private boolean isWaitForList;
/**
* Creates a new instance of ActiveTaskModule.
*
* @param descriptorLocation the module descriptor.
* @throws ModuleException when errors encountered when loading the module descriptor.
*/
public ActiveTaskModule(String descriptorLocation) {
super(descriptorLocation);
}
/**
* Creates a new instance of ActiveTaskModule.
*
* @param descriptorLocation the module descriptor.
* @param shouldInitialize true if the module should be initialized.
* @throws ModuleException when errors encountered when loading the module descriptor.
*/
public ActiveTaskModule(String descriptorLocation, boolean shouldInitialize) {
super(descriptorLocation, shouldInitialize);
}
/**
* Creates a new instance of ActiveTaskModule.
*
* @param descriptorLocation the module descriptor.
* @param loader the class loader for this module.
* @throws ModuleException when errors encountered when loading the module descriptor.
*/
public ActiveTaskModule(String descriptorLocation, ClassLoader loader) {
super(descriptorLocation, loader);
}
/**
* Creates a new instance of ActiveTaskModule.
*
* @param descriptorLocation the module descriptor.
* @param loader the class loader for this module.
* @param shouldInitialize true if the module should be initialized.
* @throws ModuleException when errors encountered when loading the module descriptor.
*/
public ActiveTaskModule(String descriptorLocation, ClassLoader loader,
boolean shouldInitialize) {
super(descriptorLocation, loader, shouldInitialize);
}
/**
* Initializes this module by loading the active task list component named
* "task-list". The component may have the following parameters:
* <ul>
* <li>max-thread-count: the maximum number of threads which can be acquired
* to execute the tasks in the task list. A number smaller than 1
* indicates the tasks should be run under the same thread as this
* module.
* <li>wait-for-list: true if the tasks in the task list should be
* completely executed before being refreshed.
* </ul>
*
* @see hk.hku.cecid.piazza.commons.module.Module#init()
*/
public void init() {
super.init();
taskList = (ActiveTaskList)getComponent("task-list");
Properties taskListParams = taskList.getParameters();
maxThreadCount = StringUtilities.parseInt(taskListParams.getProperty("max-thread-count"), 0);
isWaitForList = StringUtilities.parseBoolean(taskListParams.getProperty("wait-for-list"));
monitor.setMaxThreadCount(maxThreadCount);
}
/**
* Suspends the active monitor so that no more threads can be acquired for
* executing tasks.
*
* @see hk.hku.cecid.piazza.commons.module.ActiveModule#stop()
* @see hk.hku.cecid.piazza.commons.module.ActiveModule#onStop()
*/
public void onStop() {
getLogger().debug("Suspending active monitor in module ("+getName()+"). Current active threads: "+monitor.getThreadCount());
monitor.suspend();
}
/**
* Resumes the active monitor so that new threads can be acquired for
* executing tasks.
*
* @see hk.hku.cecid.piazza.commons.module.ActiveModule#start()
* @see hk.hku.cecid.piazza.commons.module.ActiveModule#onStart()
*/
public void onStart() {
getLogger().debug("Resuming active monitor in module ("+getName()+"). Current active threads: "+monitor.getThreadCount());
monitor.resume();
}
/**
* Invoked by the start() method to start executing the managed task list
* and its tasks.
*
* @return true if the active monitor of this module is not suspended.
* @see hk.hku.cecid.piazza.commons.module.ActiveModule#execute()
*/
public boolean execute() {
if (taskList != null) {
if (isWaitForList) {
monitor.waitForEmpty();
}
Iterator tasks = taskList.getTaskList().iterator();
while (tasks.hasNext()) {
ActiveTask task = (ActiveTask) tasks.next();
ActiveThread thread = null;
try {
thread = monitor.acquireThread();
if (thread == null) {
return false;
}
thread.setTask(task);
thread.start();
} catch (Throwable e) {
monitor.releaseThread(thread);
getLogger().error("Error in executing active task", e);
}
}
return true;
}
else {
return false;
}
}
/**
* Gets the monitor of this module.
*
* @return the monitor of this module.
*/
public ActiveMonitor getMonitor() {
return monitor;
}
}