package uk.ac.diamond.scisoft.analysis.processing.actor.runner;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.dawb.passerelle.common.actors.ActorUtils;
import org.eclipse.dawnsci.analysis.api.processing.ExecutionType;
import org.eclipse.dawnsci.analysis.api.processing.IOperationContext;
import org.eclipse.dawnsci.analysis.api.processing.IOperationRunner;
import ptolemy.moml.MoMLParser;
import com.isencia.passerelle.model.Flow;
import com.isencia.passerelle.model.FlowManager;
/**
* Builds a graph for executing with Passerelle
*
* @author Matthew Gerring
*
*/
public class GraphRunner implements IOperationRunner {
private IOperationContext context;
public void init(IOperationContext context) throws Exception {
this.context = context;
if (context.getVisitor()!=null) {
context.getVisitor().init(context.getSeries(), context.getData());
}
}
public void execute() throws Exception {
long start = System.currentTimeMillis();
MoMLParser.purgeAllModelRecords();
GraphBuilder builder = new GraphBuilder();
builder.init(context);
Flow flow = builder.createEventDirectorFlow();
try {
// We switch off being able to remotely debug the workflow
ActorUtils.setCanNotify(false);
// We run the workflow
FlowManager flowMgr = new FlowManager();
if (context.getParallelTimeout()<1) { // No timeout
flowMgr.executeBlockingErrorLocally(flow, new HashMap<String, String>());
} else {
executeGraphWithTimeout(flowMgr, flow);
}
} finally {
// We put it back
ActorUtils.setCanNotify(true);
}
logger.debug("Data ran in: " +(System.currentTimeMillis()-start)/1000. + " s");
}
/**
* Executes the workflow in another thread but throws an exception if
* the timeout is reached.
*
* @param flowMgr
* @param flow
* @throws Exception
*/
private void executeGraphWithTimeout(final FlowManager flowMgr, final Flow flow) throws Exception {
final Thread mainThread = Thread.currentThread();
final List<Exception> except = new ArrayList<Exception>(1);
final Thread workerThread = new Thread(new Runnable() {
public void run() {
try {
flowMgr.executeBlockingErrorLocally(flow, new HashMap<String, String>());
} catch (Exception ne) {
except.add(ne);
} finally {
mainThread.interrupt();
}
}
});
workerThread.start();
try {
Thread.sleep(context.getParallelTimeout());
throw new Exception("The timeout of "+context.getParallelTimeout()+" ms has been exceeded!");
} catch (InterruptedException expected) {
if (!except.isEmpty()) throw except.get(0);
// Otherwise it worked ok
}
}
@Override
public ExecutionType[] getExecutionTypes() {
return new ExecutionType[]{ExecutionType.GRAPH};
}
}