// This software is released into the Public Domain. See copying.txt for details.
package org.openstreetmap.osmosis.core.pipeline.common;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openstreetmap.osmosis.core.OsmosisRuntimeException;
/**
* This task manager implementation supports tasks that perform active
* processing in a separate thread.
*
* @author Brett Henderson
*/
public abstract class ActiveTaskManager extends TaskManager {
private static final Logger LOG = Logger.getLogger(ActiveTaskManager.class.getName());
private TaskRunner thread;
/**
* Creates a new instance.
*
* @param taskId
* A unique identifier for the task. This is used to produce
* meaningful errors when errors occur.
* @param pipeArgs
* The arguments defining input and output pipes for the task,
* pipes are a logical concept for identifying how the tasks are
* connected together.
*/
protected ActiveTaskManager(String taskId, Map<String, String> pipeArgs) {
super(taskId, pipeArgs);
}
/**
* Returns the runnable task managed by this manager.
*
* @return The task.
*/
protected abstract Runnable getTask();
/**
* {@inheritDoc}
*/
@Override
public void execute() {
LOG.fine("Launching task " + getTaskId() + " in a new thread.");
if (thread != null) {
throw new OsmosisRuntimeException("Task " + getTaskId()
+ " is already running.");
}
thread = new TaskRunner(getTask(), "Thread-" + getTaskId());
thread.start();
}
/**
* {@inheritDoc}
*/
@Override
public boolean waitForCompletion() {
LOG.fine("Waiting for task " + getTaskId() + " to complete.");
if (thread != null) {
boolean successful;
try {
thread.join();
} catch (InterruptedException e) {
// We are already in an error condition so log and continue.
LOG.log(Level.WARNING, "The wait for task completion was interrupted.", e);
}
successful = thread.isSuccessful();
if (!successful) {
LOG.log(Level.SEVERE, "Thread for task " + getTaskId() + " failed", thread.getException());
}
thread = null;
return successful;
}
return true;
}
}