use of org.ow2.proactive.scheduler.common.task.flow.FlowAction in project scheduling by ow2-proactive.
the class FlowScript method getResult.
@Override
protected ScriptResult<FlowAction> getResult(Object evalResult, Bindings bindings) {
try {
FlowAction act = new FlowAction();
/*
* no action defined
*/
if (this.actionType == null || this.actionType.equals(FlowActionType.CONTINUE.toString())) {
act.setType(FlowActionType.CONTINUE);
} else /*
* loop
*/
if (this.actionType.equals(FlowActionType.LOOP.toString())) {
if (this.target == null) {
String msg = "LOOP control flow action requires a target";
logger.error(msg);
return new ScriptResult<FlowAction>(new Exception(msg));
} else {
if (bindings.containsKey(loopVariable)) {
Boolean enabled;
String loopValue = bindings.get(loopVariable).toString();
if ("true".equalsIgnoreCase(loopValue)) {
enabled = Boolean.TRUE;
} else if ("false".equalsIgnoreCase(loopValue)) {
enabled = Boolean.FALSE;
} else {
try {
(new Predictor(loopValue)).nextMatchingDate();
enabled = Boolean.TRUE;
act.setCronExpr(loopValue);
} catch (InvalidPatternException e) {
enabled = Boolean.FALSE;
}
}
if (enabled) {
act.setType(FlowActionType.LOOP);
act.setTarget(this.target);
} else {
act.setType(FlowActionType.CONTINUE);
}
} else {
String msg = "Script environment for LOOP action needs to define variable " + loopVariable;
logger.error(msg);
return new ScriptResult<FlowAction>(new Exception(msg));
}
}
} else /*
* replicate
*/
if (this.actionType.equals(FlowActionType.REPLICATE.toString())) {
if (bindings.containsKey(replicateRunsVariable)) {
act.setType(FlowActionType.REPLICATE);
int args = 1;
Object o = bindings.get(replicateRunsVariable);
try {
args = Integer.parseInt("" + o);
} catch (NumberFormatException e) {
try {
args = (int) Math.floor(Double.parseDouble("" + o));
} catch (Exception e2) {
String msg = "REPLICATE action: could not parse value for variable " + replicateRunsVariable;
logger.error(msg);
return new ScriptResult<FlowAction>(new Exception(msg, e2));
}
}
if (args < 0) {
String msg = "REPLICATE action: value of variable " + replicateRunsVariable + " cannot be negative";
logger.error(msg);
return new ScriptResult<FlowAction>(new Exception(msg));
}
act.setDupNumber(args);
} else {
String msg = "Script environment for REPLICATE action needs to define variable " + replicateRunsVariable;
logger.error(msg);
return new ScriptResult<FlowAction>(new Exception(msg));
}
} else /*
* if
*/
if (this.actionType.equals(FlowActionType.IF.toString())) {
if (this.target == null) {
String msg = "IF action requires a target ";
logger.error(msg);
return new ScriptResult<FlowAction>(new Exception(msg));
} else if (this.targetElse == null) {
String msg = "IF action requires an ELSE target ";
logger.error(msg);
return new ScriptResult<FlowAction>(new Exception(msg));
} else {
act.setType(FlowActionType.IF);
if (bindings.containsKey(branchSelectionVariable)) {
String val = new String((String) bindings.get(branchSelectionVariable));
if (val.toLowerCase().equals(ifBranchSelectedVariable)) {
act.setTarget(this.target);
act.setTargetElse(this.targetElse);
} else if (val.toLowerCase().equals(elseBranchSelectedVariable)) {
act.setTarget(this.targetElse);
act.setTargetElse(this.target);
} else {
String msg = "IF action: value for " + branchSelectionVariable + " needs to be one of " + ifBranchSelectedVariable + " or " + elseBranchSelectedVariable;
logger.error(msg);
return new ScriptResult<FlowAction>(new Exception(msg));
}
} else {
String msg = "Environment for IF action needs to define variable " + branchSelectionVariable;
logger.error(msg);
return new ScriptResult<FlowAction>(new Exception(msg));
}
if (this.targetContinuation != null) {
act.setTargetContinuation(this.targetContinuation);
}
}
} else /*
* unknown action
*/
{
String msg = actionType + " action type unknown";
logger.error(msg);
return new ScriptResult<FlowAction>(new Exception(msg));
}
return new ScriptResult<FlowAction>(act);
} catch (Throwable th) {
return new ScriptResult<FlowAction>(th);
}
}
use of org.ow2.proactive.scheduler.common.task.flow.FlowAction in project scheduling by ow2-proactive.
the class SchedulerDBManagerTest method terminateJob.
private void terminateJob(int jobIndex, long finishedTime) throws Throwable {
InternalJob finishedJob = actualInternalJobs.get(jobIndex);
finishedJob.start();
finishedJob.terminate();
for (InternalTask task : finishedJob.getITasks()) {
TaskResultImpl result = new TaskResultImpl(task.getId(), "ok", null, 0);
FlowAction action = new FlowAction(FlowActionType.CONTINUE);
ChangedTasksInfo changesInfo = finishedJob.terminateTask(false, task.getId(), null, action, result);
task.setFinishedTime(finishedTime);
dbManager.updateAfterWorkflowTaskFinished(finishedJob, changesInfo, result);
}
}
use of org.ow2.proactive.scheduler.common.task.flow.FlowAction in project scheduling by ow2-proactive.
the class TerminateIfTaskHandler method searchIfElseJoinTasks.
private InternalTask[] searchIfElseJoinTasks(FlowAction action, InternalTask initiator) {
InternalTask targetIf = null;
InternalTask targetElse = null;
InternalTask targetJoin = null;
// search for the targets as perfect matches of the unique name
for (InternalTask it : internalJob.getIHMTasks().values()) {
// target is finished : probably looped
if (it.getStatus().equals(TaskStatus.FINISHED) || it.getStatus().equals(TaskStatus.SKIPPED)) {
continue;
}
if (action.getTarget().equals(it.getName())) {
if (it.getIfBranch().equals(initiator)) {
targetIf = it;
}
} else if (action.getTargetElse().equals(it.getName())) {
if (it.getIfBranch().equals(initiator)) {
targetElse = it;
}
} else if (action.getTargetContinuation().equals(it.getName())) {
InternalTask up = internalJob.findTask(initiator.getName());
if (up != null && up.equals(initiator)) {
targetJoin = it;
}
}
}
boolean searchIf = (targetIf == null);
boolean searchElse = (targetElse == null);
boolean searchJoin = (targetJoin == null);
// but the highest iteration index
for (InternalTask it : internalJob.getIHMTasks().values()) {
// does not share the same dup index : cannot be the same scope
if (it.getReplicationIndex() != initiator.getReplicationIndex()) {
continue;
}
if (it.getStatus().equals(TaskStatus.FINISHED) || it.getStatus().equals(TaskStatus.SKIPPED)) {
continue;
}
String name = InternalTask.getInitialName(it.getName());
if (searchIf && InternalTask.getInitialName(action.getTarget()).equals(name)) {
if (targetIf == null || targetIf.getIterationIndex() < it.getIterationIndex()) {
targetIf = it;
}
} else if (searchElse && InternalTask.getInitialName(action.getTargetElse()).equals(name)) {
if (targetElse == null || targetElse.getIterationIndex() < it.getIterationIndex()) {
targetElse = it;
}
} else if (searchJoin && InternalTask.getInitialName(action.getTargetContinuation()).equals(name)) {
if (targetJoin == null || targetJoin.getIterationIndex() < it.getIterationIndex()) {
targetJoin = it;
}
}
}
InternalTask[] result = { targetIf, targetElse, targetJoin };
return result;
}
use of org.ow2.proactive.scheduler.common.task.flow.FlowAction in project scheduling by ow2-proactive.
the class TerminateReplicateTaskHandler method terminateReplicateTask.
public boolean terminateReplicateTask(FlowAction action, InternalTask initiator, ChangedTasksInfo changesInfo, SchedulerStateUpdate frontend, TaskId taskId) {
int runs = action.getDupNumber();
logger.info("Control Flow Action REPLICATE (runs:" + runs + ")");
List<InternalTask> toReplicate = new ArrayList<>();
// find the tasks that need to be replicated
for (InternalTask internalTask : internalJob.getIHMTasks().values()) {
List<InternalTask> internalTaskDependencies = internalTask.getIDependences() == null ? new ArrayList<InternalTask>() : internalTask.getIDependences();
for (InternalTask internalTaskDependency : internalTaskDependencies) {
if (isTheInitiatorTask(initiator, toReplicate, internalTask, internalTaskDependency)) {
if (runs < 1) {
skipReplication(initiator, changesInfo, internalTask);
break;
} else {
toReplicate.add(internalTask);
}
}
}
}
// for each initial task to replicate
for (InternalTask internalTaskToReplicate : toReplicate) {
// determine the target of the replication whether it is a block or
// a single task
InternalTask target = null;
// target is a task block start : replication of the block
if (internalTaskToReplicate.getFlowBlock().equals(FlowBlock.START)) {
String tg = internalTaskToReplicate.getMatchingBlock();
for (InternalTask internalTask : internalJob.getIHMTasks().values()) {
if (tg.equals(internalTask.getName()) && !(internalTask.getStatus().equals(TaskStatus.FINISHED) || internalTask.getStatus().equals(TaskStatus.SKIPPED)) && internalTask.dependsOn(internalTaskToReplicate)) {
target = internalTask;
break;
}
}
if (target == null) {
logger.error("REPLICATE: could not find matching block '" + tg + "'");
continue;
}
} else // target is not a block : replication of the task
{
target = internalTaskToReplicate;
}
// for each number of parallel run
for (int i = 1; i < runs; i++) {
// accumulates the tasks between the initiator and the target
Map<TaskId, InternalTask> tasksBetweenInitiatorAndTarget = new HashMap<>();
// replicate the tasks between the initiator and the target
try {
target.replicateTree(tasksBetweenInitiatorAndTarget, internalTaskToReplicate.getId(), false, initiator.getReplicationIndex() * runs, 0);
} catch (Exception e) {
logger.error("REPLICATE: could not replicate tree", e);
break;
}
((JobInfoImpl) internalJob.getJobInfo()).setNumberOfPendingTasks(((JobInfoImpl) internalJob.getJobInfo()).getNumberOfPendingTasks() + tasksBetweenInitiatorAndTarget.size());
// pointers to the new replicated tasks corresponding the begin
// and
// the end of the block ; can be the same
InternalTask newTarget = null;
InternalTask newEnd = null;
// configure the new tasks
for (InternalTask internalTask : tasksBetweenInitiatorAndTarget.values()) {
internalTask.setJobInfo(((JobInfoImpl) internalJob.getJobInfo()));
int dupIndex = getNextReplicationIndex(InternalTask.getInitialName(internalTask.getName()), internalTask.getIterationIndex());
internalJob.addTask(internalTask);
internalTask.setReplicationIndex(dupIndex);
assignReplicationTag(internalTask, initiator, false, action);
}
changesInfo.newTasksAdded(tasksBetweenInitiatorAndTarget.values());
// find the beginning and the ending of the replicated block
for (Entry<TaskId, InternalTask> tasksBetweenInitiatorAndTargetEntry : tasksBetweenInitiatorAndTarget.entrySet()) {
InternalTask internalBlockTask = tasksBetweenInitiatorAndTargetEntry.getValue();
// initiator
if (internalTaskToReplicate.getId().equals(tasksBetweenInitiatorAndTargetEntry.getKey())) {
newTarget = internalBlockTask;
newTarget.addDependence(initiator);
// no need to add newTarget to modifiedTasks
// because newTarget is among dup.values(), and we
// have added them all
}
// connect the last task of the block with the merge task(s)
if (target.getId().equals(tasksBetweenInitiatorAndTargetEntry.getKey())) {
newEnd = internalBlockTask;
List<InternalTask> toAdd = new ArrayList<>();
// find the merge tasks ; can be multiple
for (InternalTask internalTask : internalJob.getIHMTasks().values()) {
List<InternalTask> pdeps = internalTask.getIDependences();
if (pdeps != null) {
for (InternalTask parent : pdeps) {
if (parent.getId().equals(target.getId())) {
toAdd.add(internalTask);
}
}
}
}
// connect the merge tasks
for (InternalTask internalTask : toAdd) {
internalTask.addDependence(newEnd);
changesInfo.taskUpdated(internalTask);
}
}
}
// propagate the changes on the JobDescriptor
internalJob.getJobDescriptor().doReplicate(taskId, tasksBetweenInitiatorAndTarget, newTarget, target.getId(), newEnd.getId());
}
}
// notify frontend that tasks were added to the job
((JobInfoImpl) internalJob.getJobInfo()).setTasksChanges(changesInfo, internalJob);
if (frontend != null) {
frontend.jobStateUpdated(internalJob.getOwner(), new NotificationData<>(SchedulerEvent.TASK_REPLICATED, internalJob.getJobInfo()));
frontend.jobStateUpdated(internalJob.getOwner(), new NotificationData<>(SchedulerEvent.TASK_SKIPPED, internalJob.getJobInfo()));
frontend.jobUpdatedFullData(internalJob);
}
((JobInfoImpl) internalJob.getJobInfo()).clearTasksChanges();
// no jump is performed ; now that the tasks have been replicated and
// configured, the flow can continue its normal operation
internalJob.getJobDescriptor().terminate(taskId);
return true;
}
use of org.ow2.proactive.scheduler.common.task.flow.FlowAction in project scheduling by ow2-proactive.
the class TestTaskResultData method testFlowAction.
@Test
public void testFlowAction() throws Exception {
InternalJob job = saveSingleTask(createDefaultTask("task"));
InternalTask task = (InternalTask) job.getTasks().get(0);
TaskResultImpl result = new TaskResultImpl(null, new TestResult(10, "12345"), null, 0);
FlowAction action = new FlowAction(FlowActionType.LOOP);
action.setDupNumber(33);
action.setTarget("t");
action.setTargetContinuation("tc");
action.setTargetElse("te");
result.setAction(action);
dbManager.updateAfterTaskFinished(job, task, result);
TaskResultImpl restoredResult = (TaskResultImpl) dbManager.loadLastTaskResult(task.getId());
FlowAction restoredAction = restoredResult.getAction();
Assert.assertNotNull(restoredAction);
Assert.assertEquals(FlowActionType.LOOP, restoredAction.getType());
Assert.assertEquals(33, restoredAction.getDupNumber());
Assert.assertEquals("t", restoredAction.getTarget());
Assert.assertEquals("tc", restoredAction.getTargetContinuation());
Assert.assertEquals("te", restoredAction.getTargetElse());
restoredResult = (TaskResultImpl) dbManager.loadTaskResult(job.getId(), "task", 0);
restoredAction = restoredResult.getAction();
Assert.assertEquals(FlowActionType.LOOP, restoredAction.getType());
}
Aggregations