package org.goko.core.execution.monitor.service;
import org.goko.core.common.exception.GkException;
import org.goko.core.gcode.execution.ExecutionQueue;
import org.goko.core.gcode.execution.ExecutionState;
import org.goko.core.gcode.execution.IExecutionControl;
import org.goko.core.gcode.execution.IExecutionToken;
import org.goko.core.gcode.execution.IExecutionTokenState;
import org.goko.core.gcode.execution.IExecutor;
import org.goko.core.gcode.service.IExecutionService;
import org.goko.core.log.GkLog;
/**
* Describes a runnable performing the execution of an ExecutionQueue
*
* @author Psyko
*
*/
public class ExecutionQueueRunnable<S extends IExecutionTokenState, T extends IExecutionToken<S>> implements Runnable,IExecutionControl{
/** LOG */
private static final GkLog LOG = GkLog.getLogger(ExecutionQueueRunnable.class);
/** The current executor */
private IExecutor<S, T> executor;
/** The execution queue*/
private ExecutionQueue<S, T> executionQueue;
/** The underlying execution service */
private IExecutionService<S, T> executionService;
/** The state of the execution */
private ExecutionState state;
/**
* Constructor
* @param executionService the referencing execution service
*/
public ExecutionQueueRunnable(IExecutionService<S, T> executionService) {
this.executionService = executionService;
this.state = ExecutionState.IDLE;
}
/** (inheritDoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
LOG.info("Starting ExecutionQueueRunnable");
try{
setState(ExecutionState.RUNNING);
executionService.notifyQueueExecutionStart(executionQueue.getType());
while(executionQueue.hasNext() && state != ExecutionState.STOPPED){
executionQueue.beginNextTokenExecution();
runExecutionToken();
executionQueue.endCurrentTokenExecution();
}
if(state == ExecutionState.STOPPED){
executionService.notifyQueueExecutionCanceled(executionQueue.getType());
}else if(state == ExecutionState.ERROR){
executionService.notifyQueueExecutionCanceled(executionQueue.getType());
}else{
setState(ExecutionState.COMPLETE);
executionService.notifyQueueExecutionComplete(executionQueue.getType());
LOG.info("Queue complete");
}
}catch(GkException e){
LOG.error(e);
setState(ExecutionState.FATAL_ERROR);
}
}
protected void isValidState(){
}
/**
* Execute the given execution token
* @param token the token to execute
* @throws GkException GkException
*/
protected void runExecutionToken() throws GkException{
executor.setExecutionService(executionService);
T token = executionQueue.getCurrentToken();
executor.executeToken(token);
}
/**
* @return the executor
*/
public IExecutor<S, T> getExecutor() {
return executor;
}
/**
* @param executor the executor to set
*/
public void setExecutor(IExecutor<S, T> executor) {
this.executor = executor;
}
/**
* @return the executionQueue
*/
public ExecutionQueue<S, T> getExecutionQueue() {
return executionQueue;
}
/**
* @param executionQueue the executionQueue to set
*/
public void setExecutionQueue(ExecutionQueue<S, T> executionQueue) {
this.executionQueue = executionQueue;
}
/**
* @return the state
*/
@Override
public ExecutionState getState() {
return state;
}
/**
* @param state the state to set
*/
public void setState(ExecutionState state) {
this.state = state;
}
/** (inheritDoc)
* @see org.goko.core.gcode.execution.IExecutionControl#start()
*/
@Override
public void start() throws GkException {
executor.start();
setState(ExecutionState.RUNNING);
executionService.notifyExecutionStart(executionQueue.getCurrentToken());
}
/** (inheritDoc)
* @see org.goko.core.gcode.execution.IExecutionControl#resume()
*/
@Override
public void resume() throws GkException {
if(getState() == ExecutionState.PAUSED){
setState(ExecutionState.RUNNING);
executor.resume();
executionService.notifyExecutionResume(executionQueue.getCurrentToken());
}
}
/** (inheritDoc)
* @see org.goko.core.gcode.execution.IExecutionControl#pause()
*/
@Override
public void pause() throws GkException {
if(getState() == ExecutionState.RUNNING){
setState(ExecutionState.PAUSED);
executor.pause();
executionService.notifyExecutionPause(executionQueue.getCurrentToken());
}
}
/** (inheritDoc)
* @see org.goko.core.gcode.execution.IExecutionControl#stop()
*/
@Override
public void stop() throws GkException {
if(getState() == ExecutionState.RUNNING || getState() == ExecutionState.PAUSED){
T token = executionQueue.getCurrentToken();
setState(ExecutionState.STOPPED);
executor.stop();
executionService.notifyExecutionCanceled(token);
}
}
}