private void checkTasks(JobInfo info) { if (keep(info)) { TaskInfo tinfo = info.getTaskInfo(); if (tinfo != null) { JobTreeElement[] toBeRemoved = null; boolean fire = false; JobTreeElement element = (JobTreeElement) tinfo.getParent(); synchronized (keptjobinfos) { if (element == info && !keptjobinfos.contains(tinfo)) { toBeRemoved = findJobsToRemove(element); keptjobinfos.add(tinfo); finishedTime.put(tinfo, new Long(System.currentTimeMillis())); } } if (toBeRemoved != null) { for (int i = 0; i < toBeRemoved.length; i++) { remove(toBeRemoved[i]); } } if (fire) { Object l[] = getListeners(); for (int i = 0; i < l.length; i++) { KeptJobsListener jv = (KeptJobsListener) l[i]; jv.finished(info); } } } } }
private boolean allTasksComplete() { for (TaskInfo taskInfo : executionPlan.values()) { if (!taskInfo.isComplete()) { return false; } } return true; }
private TaskInfo getNextReadyAndMatching(Spec<TaskInfo> criteria) { for (TaskInfo taskInfo : executionPlan.values()) { if (taskInfo.isReady() && criteria.isSatisfiedBy(taskInfo)) { return taskInfo; } } return null; }
private void abortExecution() { // Allow currently executing tasks to complete, but skip everything else. for (TaskInfo taskInfo : executionPlan.values()) { if (taskInfo.isReady()) { taskInfo.skipExecution(); } } }
public void taskComplete(TaskInfo taskInfo) { lock.lock(); try { if (taskInfo.isFailed()) { handleFailure(taskInfo); } taskInfo.finishExecution(); runningProjects.remove(taskInfo.getTask().getProject().getPath()); condition.signalAll(); } finally { lock.unlock(); } }
public void save(TaskInfo<?> taskInfo) { try { File taskDirectory = getTaskDirectory(taskInfo.getId()); FileUtils.forceMkdir(taskDirectory); File tmpFile = new File(taskDirectory, UUID.randomUUID().toString()); File infoFile = getTaskInfoFile(taskInfo.getId()); objectMapper.writeValue(tmpFile, taskInfo); Files.move( tmpFile.toPath(), infoFile.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { throw Throwables.propagate(e); } }
private void handleFailure(TaskInfo taskInfo) { Throwable executionFailure = taskInfo.getExecutionFailure(); if (executionFailure != null) { // Always abort execution for an execution failure (as opposed to a task failure) abortExecution(); this.failures.add(executionFailure); return; } // Task failure try { failureHandler.onTaskFailure(taskInfo.getTask()); this.failures.add(taskInfo.getTaskFailure()); } catch (Exception e) { // If the failure handler rethrows exception, then execution of other tasks is aborted. // (--continue will collect failures) abortExecution(); this.failures.add(e); } }
public TaskInfo getTaskToExecute(Spec<TaskInfo> criteria) { lock.lock(); try { TaskInfo nextMatching; while ((nextMatching = getNextReadyAndMatching(criteria)) != null) { while (!nextMatching.allDependenciesComplete()) { try { condition.await(); } catch (InterruptedException e) { throw new RuntimeException(e); } } // The task state could have been modified while we waited for dependency completion. Check // that it is still 'ready'. if (!nextMatching.isReady()) { continue; } if (nextMatching.allDependenciesSuccessful()) { nextMatching.startExecution(); return nextMatching; } else { nextMatching.skipExecution(); condition.signalAll(); } } return null; } finally { lock.unlock(); } }
public TaskInfo getTaskToExecute() { lock.lock(); try { while (true) { TaskInfo nextMatching = null; boolean allTasksComplete = true; for (TaskInfo taskInfo : executionPlan.values()) { allTasksComplete = allTasksComplete && taskInfo.isComplete(); if (taskInfo.isReady() && taskInfo.allDependenciesComplete() && !runningProjects.contains(taskInfo.getTask().getProject().getPath())) { nextMatching = taskInfo; break; } } if (allTasksComplete) { return null; } if (nextMatching == null) { try { condition.await(); } catch (InterruptedException e) { throw new RuntimeException(e); } } else { if (nextMatching.allDependenciesSuccessful()) { nextMatching.startExecution(); runningProjects.add(nextMatching.getTask().getProject().getPath()); return nextMatching; } else { nextMatching.skipExecution(); condition.signalAll(); } } } } finally { lock.unlock(); } }
public void determineExecutionPlan() { List<TaskInfo> nodeQueue = CollectionUtils.collect( new ArrayList<Task>(entryTasks), new Transformer<TaskInfo, Task>() { public TaskInfo transform(Task original) { return graph.getNode(original); } }); Set<TaskInfo> visitingNodes = new HashSet<TaskInfo>(); while (!nodeQueue.isEmpty()) { TaskInfo taskNode = nodeQueue.get(0); boolean filtered = !filter.isSatisfiedBy(taskNode.getTask()); if (filtered) { taskNode.setRequired(false); } if (!taskNode.getRequired() || executionPlan.containsKey(taskNode.getTask())) { nodeQueue.remove(0); continue; } if (visitingNodes.add(taskNode)) { // Have not seen this task before - add its dependencies to the head of the queue and leave // this // task in the queue ArrayList<TaskInfo> dependsOnTasks = new ArrayList<TaskInfo>(); addAllReversed(dependsOnTasks, taskNode.getHardSuccessors()); addAllReversed(dependsOnTasks, taskNode.getSoftSuccessors()); for (TaskInfo dependsOnTask : dependsOnTasks) { if (visitingNodes.contains(dependsOnTask)) { throw new CircularReferenceException( String.format( "Circular dependency between tasks. Cycle includes [%s, %s].", taskNode.getTask(), dependsOnTask.getTask())); } nodeQueue.add(0, dependsOnTask); } } else { // Have visited this task's dependencies - add it to the end of the plan nodeQueue.remove(0); visitingNodes.remove(taskNode); executionPlan.put(taskNode.getTask(), taskNode); } } }