public void addToTaskGraph(Collection<? extends Task> tasks) { List<Task> queue = new ArrayList<Task>(tasks); Collections.sort(queue); entryTasks.addAll(queue); Set<Task> visiting = new HashSet<Task>(); CachingTaskDependencyResolveContext context = new CachingTaskDependencyResolveContext(); while (!queue.isEmpty()) { Task task = queue.get(0); if (graph.hasTask(task) && graph.getNode(task).getRequired()) { queue.remove(0); continue; } if (visiting.add(task)) { // Have not seen this task before - add its dependencies to the head of the queue and leave // this // task in the queue Set<Task> dependsOnTasks = new TreeSet<Task>(Collections.reverseOrder()); dependsOnTasks.addAll(context.getDependencies(task)); for (Task dependsOnTask : dependsOnTasks) { if (visiting.contains(dependsOnTask)) { throw new CircularReferenceException( String.format( "Circular dependency between tasks. Cycle includes [%s, %s].", task, dependsOnTask)); } queue.add(0, dependsOnTask); } } else { // Have visited this task's dependencies - add it to the graph queue.remove(0); visiting.remove(task); TaskInfo node = graph.addNode(task); Set<? extends Task> dependencies = context.getDependencies(task); for (Task dependency : dependencies) { graph.addHardEdge(node, dependency); } for (Task mustRunAfter : task.getMustRunAfter().getDependencies(task)) { graph.addSoftEdge(node, mustRunAfter); } } } }
public void clear() { lock.lock(); try { graph.clear(); entryTasks.clear(); executionPlan.clear(); failures.clear(); runningProjects.clear(); } finally { lock.unlock(); } }