void InitializeProjectOptions(BuildNode node) { IBuildable project = node.project; // Create options for building the project node.options = project.CreateProjectBuildOptions(options, project == rootProject); }
void InitializeDependencies(BuildNode node) { // Initialize dependencies if (options.BuildDependentProjects) { var dependencies = node.project.GetBuildDependencies(node.options); if (dependencies != null) { node.dependencies = dependencies .Select <IBuildable, BuildNode>(CreateBuildGraph) .Distinct().ToArray(); } } if (node.dependencies == null) { node.dependencies = new BuildNode[0]; } node.outstandingDependencies = node.dependencies.Length; foreach (BuildNode d in node.dependencies) { if (!d.nodeComplete) { throw new CyclicDependencyException(node.project, d.project); } d.dependentOnThis.Add(node); } if (node.outstandingDependencies == 0) { projectsReadyForBuildStart.Add(node); } }
void OnBuildFinished(BuildNode node, bool success) { ICSharpCode.Core.LoggingService.Info("Finished building " + node.project.Name); lock (this) { if (node.buildFinished) { throw new InvalidOperationException("This node already finished building, do not call IBuildFeedbackSink.Done() multiple times!"); } runningWorkers--; node.buildFinished = true; node.hasErrors = !success; projectsCurrentlyBuilding.Remove(node); results.AddBuiltProject(node.project); if (progressMonitor != null) { progressMonitor.WorkDone += 1; } foreach (BuildNode n in node.dependentOnThis) { n.outstandingDependencies--; if (n.outstandingDependencies == 0) { projectsReadyForBuildStart.Add(n); } } workersToStart++; } LogBuildFinished(node); StartBuildProjects(); UpdateProgressTaskName(); }
static int CompareBuildOrder(BuildNode a, BuildNode b) { // When the build graph looks like this: // 1 2 // \ / \ // 3 4 // / \ // 5 6 // And we have 2 build workers, determining the build order alphabetically only would result // in this order: // 4, 5 // 6 // 3 // 1, 2 // However, we can build faster if we build 5+6 first: // 5, 6 // 3, 4 // 1, 2 // // As heuristic, we first build the projects that have the most projects dependent on it. int r = -(a.TotalDependentOnThisCount.CompareTo(b.TotalDependentOnThisCount)); if (r == 0) { r = string.Compare(a.project.Name, b.project.Name, StringComparison.CurrentCultureIgnoreCase); } return(r); }
void LogBuildFinished(BuildNode node) { List <string> messagesToReport = null; bool newNodeWithOutputLockAlreadyFinishedBuilding = false; lock (this) { if (node == nodeWithOutputLock) { if (nodesWaitingForOutputLock.Count > 0) { nodeWithOutputLock = nodesWaitingForOutputLock.Dequeue(); messagesToReport = nodeWithOutputLock.unreportedMessageList; nodeWithOutputLock.unreportedMessageList = null; newNodeWithOutputLockAlreadyFinishedBuilding = nodeWithOutputLock.buildFinished; } else { nodeWithOutputLock = null; } } } if (messagesToReport != null) { messagesToReport.ForEach(ReportMessageInternal); } if (newNodeWithOutputLockAlreadyFinishedBuilding) { // if the node already finished building before it got the output lock, we need // to release the output lock again here LogBuildFinished(nodeWithOutputLock); } }
void ReportMessage(BuildNode source, string message) { bool hasOutputLock; lock (this) { if (nodeWithOutputLock == null) { nodeWithOutputLock = source; } hasOutputLock = nodeWithOutputLock == source; if (!hasOutputLock) { if (source.unreportedMessageList == null) { nodesWaitingForOutputLock.Enqueue(source); source.unreportedMessageList = new List <string>(); } source.unreportedMessageList.Add(message); } } if (hasOutputLock) { ReportMessageInternal(message); } }
void EndOneBuild(BuildNode node) { var task = ongoing_builds [node.Build]; ongoing_builds [node.Build] = null; node.Release(); }
public async Task <bool> DeployFromCommandLine(BuildNode InBuild, Project ProjectConfig) { CancellationTaskTokenSource = new CancellationTokenSource(); var Build = new BuildNode(InBuild.UseBuild, InBuild.Number, InBuild.Timestamp, InBuild.Path, InBuild.Platform, InBuild.Solution, InBuild.Role, InBuild.AutomatedTestStatus); var DeployTasks = new List <Task <bool> >(); foreach (ITargetDevice Device in Devices) { Device.ProjectConfig = ProjectConfig; Device.Build = Build; DeploymentTask = Task.Run(() => Device.DeployBuild(Build, this, CancellationTaskTokenSource.Token), CancellationTaskTokenSource.Token); DeployTasks.Add(DeploymentTask); } // Wait for all tasks Task AllTasks = Task.WhenAll(DeployTasks); await AllTasks; // Computer overall task(s) results bool OverallResult = true; foreach (Task <bool> FinishedTask in DeployTasks) { OverallResult = OverallResult && FinishedTask.Result; } return(OverallResult); }
void ValidateNode(BuildNode node) { if (string.IsNullOrEmpty(node.Command) || !_commandFactory.ContainsHandler(node.Command)) { throw new CommandNotFoundException(node.Command); } }
void LogBuildFinished(BuildNode node) { List <RichText> messagesToReport = null; bool newNodeWithOutputLockAlreadyFinishedBuilding = false; lock (this) { if (node == nodeWithOutputLock) { if (nodesWaitingForOutputLock.Count > 0) { nodeWithOutputLock = nodesWaitingForOutputLock.Dequeue(); messagesToReport = nodeWithOutputLock.unreportedMessageList; nodeWithOutputLock.unreportedMessageList = null; newNodeWithOutputLockAlreadyFinishedBuilding = nodeWithOutputLock.buildFinished; } else { nodeWithOutputLock = null; } } } if (messagesToReport != null) { // we can report these messages outside the lock: // while they swap order with messages currently coming in (ReportMessage), // this shouldn't be a problem as nodes should not report messages after they finish building. messagesToReport.ForEach(ReportMessageInternal); } if (newNodeWithOutputLockAlreadyFinishedBuilding) { // if the node already finished building before it got the output lock, we need // to release the output lock again here LogBuildFinished(nodeWithOutputLock); } }
// FIXME: take max nodes into account here, and get throttling working. BuildNode TakeNode(BuildSubmission build) { var host = BuildManager.OngoingBuildParameters.HostServices; NodeAffinity affinity; if (host == null) { affinity = NodeAffinity.Any; } else { affinity = host.GetNodeAffinity(build.BuildRequest.ProjectFullPath); } BuildNode n = GetReusableNode(affinity); if (n != null) { n.Assign(build); } else { n = new BuildNode(this, affinity == NodeAffinity.Any ? NodeAffinity.InProc : affinity); n.Assign(build); if (n.Affinity == NodeAffinity.InProc) { in_proc_nodes.Add(n); } else { out_proc_nodes.Add(n); } } return(n); }
void Start() { BuildNode[] BuildNodes = FindObjectsOfType <BuildNode>(); foreach (BuildNode BuildNode in BuildNodes) { Physics2D.IgnoreCollision(BuildNode.GetComponent <Collider2D>(), GetComponent <Collider2D>()); } }
void StartBuildProjects() { lock (this) { while (workersToStart > 0) { if (buildIsCancelled || projectsReadyForBuildStart.Count == 0) { if (runningWorkers == 0) { BuildDone(); } return; } workersToStart--; int projectToStartIndex = 0; for (int i = 1; i < projectsReadyForBuildStart.Count; i++) { if (CompareBuildOrder(projectsReadyForBuildStart[i], projectsReadyForBuildStart[projectToStartIndex]) < 0) { projectToStartIndex = i; } } BuildNode node = projectsReadyForBuildStart[projectToStartIndex]; projectsReadyForBuildStart.RemoveAt(projectToStartIndex); node.perNodeProgressMonitor = progressMonitor.CreateSubTask(1.0 / nodeDict.Count); node.buildStarted = true; bool hasDependencyErrors = false; foreach (BuildNode n in node.dependencies) { if (!n.buildFinished) { throw new Exception("Trying to build project with unfinished dependencies"); } hasDependencyErrors |= n.hasErrors; } ICSharpCode.Core.LoggingService.Info("Start building " + node.project.Name); runningWorkers++; projectsCurrentlyBuilding.Add(node); if (hasDependencyErrors) { ICSharpCode.Core.LoggingService.Debug("Skipped building " + node.project.Name + " (errors in dependencies)"); node.hasErrors = true; node.Done(false); } else { // do not run "DoStartBuild" inside lock - run it async on the thread pool System.Threading.ThreadPool.QueueUserWorkItem(node.DoStartBuild); } } } }
public void Open(BuildNode node) { CurrentBuildNode = node; window.Show (); for (int i = 0; i < node.SpawnableAgents.Length; i++) { Tiles[i].Open (node.SpawnableAgents[i]); } }
static void VisitDependentOnThis(HashSet <BuildNode> visitedNodes, BuildNode node) { if (visitedNodes.Add(node)) { foreach (BuildNode n in node.dependentOnThis) { VisitDependentOnThis(visitedNodes, n); } } }
public void Open(BuildNode node) { CurrentBuildNode = node; window.Show(); for (int i = 0; i < node.SpawnableAgents.Length; i++) { Tiles[i].Open(node.SpawnableAgents[i]); } }
public void OnBuildDeployedError(ITargetDevice Device, BuildNode Build, string ErrorMessage) { ThreadHelperClass.SetDeviceDeploymentResult(WinForm, DeviceView, Device, BuildDeploymentResult.Failure); DeployedDeviceCount++; if (Devices.Count == DeployedDeviceCount) { Callback.OnDeploymentDone(this); } }
public void OnBuildDeployedAborted(ITargetDevice Device, BuildNode Build) { ThreadHelperClass.SetDeviceDeploymentResult(WinForm, DeviceView, Device, BuildDeploymentResult.Aborted); DeployedDeviceCount++; if (Devices.Count == DeployedDeviceCount) { Callback.OnDeploymentDone(this); } }
public async Task <bool> Deploy(BuildNode InBuild) { DeployedDeviceCount = 0; CancellationTaskTokenSource = new CancellationTokenSource(); DeploymentTask = Task.Run(() => DeployBuild(InBuild, this, CancellationTaskTokenSource.Token), CancellationTaskTokenSource.Token); await DeploymentTask; return(DeploymentTask.Result); }
public void SetAvailable(string buildName) { foreach (var build in allBuild) { BuildNode node = build.GetComponent <BuildNode>(); if (node.building.objectName.Equals(buildName)) { node.SetAvailable(); } } }
public GameObject GrabGOAtNodeCoords(Vector2 nodeCoords) { foreach (GameObject go in nodes) { BuildNode node = go.GetComponent <BuildNode>(); if (node.GetNodeCoords().x == nodeCoords.x && node.GetNodeCoords().y == nodeCoords.y) { return(go); } } return(null); }
public ICommand Create(BuildNode node) { Type commandType; if (!_commands.TryGetValue(node.Command, out commandType)) { return(new NotFoundCommand()); } var commandInstance = Activator.CreateInstance(commandType) as ICommand; return(commandInstance); }
public void OnBuildDeployed(ITargetDevice Device, BuildNode Build) { if (WinForm != null && DeviceView != null) { ThreadHelperClass.SetDeviceDeploymentResult(WinForm, DeviceView, Device, BuildDeploymentResult.Success); } else { Console.WriteLine(string.Format("Build [{0}] has been successfully deployed on device [{1}]", Build.Number, Device.Name)); } Callback.OnDeploymentDone(this); }
public void OnBuildDeployedError(ITargetDevice Device, BuildNode Build, string ErrorMessage) { if (WinForm != null && DeviceView != null) { ThreadHelperClass.SetDeviceDeploymentResult(WinForm, DeviceView, Device, BuildDeploymentResult.Failure); } else { Console.WriteLine(string.Format("Following error happened while deploying build [{0}] to device [{1}] : {2}", Build.Number, Device.Name, ErrorMessage)); } Callback.OnDeploymentDone(this); }
public void StartTask(BuildNode node) { _logger.LogDebug($"BuildProcess.StartTask: Node: \"{node.Name}\""); var task = FindTask(node); if (task != null) { _logger.LogDebug($"BuildProcess.StartTask: Task: {task.GetHashCode()}"); CurrentTasks.Add(task); task.Start(); TaskStarted?.Invoke(task); } }
void ReportError(BuildNode source, BuildError error) { if (!error.IsWarning) { source.hasErrors = true; } results.Add(error); ReportMessage(source, error.ToString()); if (combinedBuildFeedbackSink != null) { combinedBuildFeedbackSink.ReportError(error); } }
public void OnBuildDeployedAborted(ITargetDevice Device, BuildNode Build) { Build.Progress = 0; if (WinForm != null && DeviceView != null) { ThreadHelperClass.SetDeviceDeploymentResult(WinForm, DeviceView, Device, BuildDeploymentResult.Aborted); } else { Console.WriteLine(string.Format("Deployment of build [{0}] to device [{1}] has been aborted !", Build.Number, Device.Name)); } Callback.OnDeploymentDone(this); }
public override void OnInspectorGUI() { m_Target = target as BuildNode; m_Target.building = EditorGUILayout.ObjectField("建筑资源", m_Target.building, typeof(BuildingSO), true) as BuildingSO; if (m_Target.building != null) { //if (m_Target.gameObject.GetComponentInChildren<Image>().sprite==null) //{ // m_Target.gameObject.GetComponentInChildren<Image>().sprite = m_Target.building.lowSource; //} //m_Target.gameObject.GetComponentInChildren<Text>().text = m_Target.building.objectName; } }
private void fillMasters(IEnumerable <BambooBuild> builds) { foreach (var build in builds) { if (build.MasterPlanKey != null) { continue; } var key = getMapPlanKeyFromBuild(build); if (!masterNodes.ContainsKey(key)) { masterNodes[key] = new BuildNode(build); } } }
/// <summary> /// 储存节点允许状态 /// </summary> /// <returns></returns> public Dictionary <int, Dictionary <string, bool> > SaveNodes() { Dictionary <int, Dictionary <string, bool> > nodes = new Dictionary <int, Dictionary <string, bool> >(); for (int i = 0; i < hierarchys.Length; i++) { Dictionary <string, bool> pairs = new Dictionary <string, bool>(); foreach (var node in hierarchys[i].GetComponentsInChildren <Transform>()) { BuildNode buildNode = node.gameObject.GetComponent <BuildNode>(); pairs.Add(buildNode.building.objectName, buildNode.isBuild); } nodes.Add(i, pairs); } return(nodes); }
BuildNode CreateBuildGraph(IBuildable project) { BuildNode node; if (nodeDict.TryGetValue(project, out node)) { return(node); } node = new BuildNode(this, project); nodeDict[project] = node; InitializeProjectOptions(node); InitializeDependencies(node); node.nodeComplete = true; return(node); }
int FindLastNonDuplicateFail(BuildNode NodeToDo, NodeHistory History, JobInfo JobInfo) { int Result = P4Env.Changelist; string GameNameIfAny = NodeToDo.GameNameIfAnyForTempStorage; var TempStorageNodeInfo = new TempStorageNodeInfo(JobInfo, NodeToDo.Name + FailedTempStorageSuffix); List<int> BackwardsFails = new List<int>(History.AllFailed); BackwardsFails.Add(P4Env.Changelist); BackwardsFails.Sort(); BackwardsFails.Reverse(); HashSet<string> CurrentErrors = null; foreach (int CL in BackwardsFails) { if (CL > P4Env.Changelist) { continue; } if (CL <= History.LastSucceeded) { break; } // Find any local temp storage manifest for this changelist and delete it. var ThisTempStorageNodeInfo = new TempStorageNodeInfo(JobInfo.CreateWithNewChangelist(CL), TempStorageNodeInfo.NodeStorageName); TempStorage.DeleteLocalTempStorageManifest(ThisTempStorageNodeInfo, true); // these all clash locally, which is fine we just retrieve them from shared List<string> Files = null; try { bool WasLocal; Files = TempStorage.RetrieveFromTempStorage(ThisTempStorageNodeInfo, out WasLocal, GameNameIfAny, CmdEnv.LocalRoot); // this will fail on our CL if we didn't fail or we are just setting up the branch } catch (Exception) { } if (Files == null) { continue; } if (Files.Count != 1) { throw new AutomationException("Unexpected number of files for fail record {0}", Files.Count); } string ErrorFile = Files[0]; HashSet<string> ThisErrors = ECJobPropsUtils.ErrorsFromProps(ErrorFile); if (CurrentErrors == null) { CurrentErrors = ThisErrors; } else { if (CurrentErrors.Count == 0 || !HashSetEqual(CurrentErrors, ThisErrors)) { break; } Result = CL; } } return Result; }
/// <summary> /// Resolve a node's dependency names to arrays of NodeInfo instances, filling in the appropriate fields in the NodeInfo object. /// </summary> /// <param name="Node"></param> /// <param name="AggregateNameToInfo">Map of other aggregate names to their corresponding instance.</param> /// <param name="NodeNameToInfo">Map from node names to their corresponding instance.</param> /// <param name="NumErrors">The number of errors output so far. Incremented if resolving this aggregate fails.</param> private static void LinkNode(BuildNode Node, Dictionary<string, AggregateNode> AggregateNameToInfo, Dictionary<string, BuildNode> NodeNameToInfo, ref int NumErrors) { if(Node.Dependencies == null) { // Find all the dependencies HashSet<BuildNode> Dependencies = new HashSet<BuildNode>(); foreach (string DependencyName in Node.Node.FullNamesOfDependencies) { if (!ResolveDependencies(DependencyName, AggregateNameToInfo, NodeNameToInfo, Dependencies)) { CommandUtils.LogError("Node {0} is not in the graph. It is a dependency of {1}.", DependencyName, Node.Name); NumErrors++; } } Node.Dependencies = Dependencies.ToArray(); // Find all the pseudo-dependencies HashSet<BuildNode> PseudoDependencies = new HashSet<BuildNode>(); foreach (string PseudoDependencyName in Node.Node.FullNamesOfPseudosependencies) { if (!ResolveDependencies(PseudoDependencyName, AggregateNameToInfo, NodeNameToInfo, PseudoDependencies)) { CommandUtils.LogError("Node {0} is not in the graph. It is a pseudodependency of {1}.", PseudoDependencyName, Node.Name); NumErrors++; } } Node.PseudoDependencies = PseudoDependencies.ToArray(); // Set the direct dependencies list Node.AllDirectDependencies = Node.Dependencies.Union(Node.PseudoDependencies).ToArray(); // Recursively find the dependencies for all the dependencies HashSet<BuildNode> IndirectDependenices = new HashSet<BuildNode>(Node.AllDirectDependencies); foreach(BuildNode DirectDependency in Node.AllDirectDependencies) { LinkNode(DirectDependency, AggregateNameToInfo, NodeNameToInfo, ref NumErrors); IndirectDependenices.UnionWith(DirectDependency.AllIndirectDependencies); } Node.AllIndirectDependencies = IndirectDependenices.ToArray(); // Check the node doesn't reference itself if(Node.AllIndirectDependencies.Contains(Node)) { CommandUtils.LogError("Node {0} has a dependency on itself.", Node.Name); NumErrors++; } } }
/// <summary> /// Recursively find the controlling triggers for the given node. /// </summary> /// <param name="NodeToDo">Node to find the controlling triggers for</param> static void FindControllingTriggers(BuildNode NodeToDo) { if(NodeToDo.ControllingTriggers == null) { NodeToDo.ControllingTriggers = new TriggerNode[0]; // Find all the dependencies of this node List<BuildNode> AllDependencies = new List<BuildNode>(); AllDependencies.AddRange(NodeToDo.Dependencies); AllDependencies.AddRange(NodeToDo.PseudoDependencies); // Find the immediate trigger controlling this one List<TriggerNode> PreviousTriggers = new List<TriggerNode>(); foreach (BuildNode Dependency in AllDependencies) { FindControllingTriggers(Dependency); TriggerNode PreviousTrigger = Dependency as TriggerNode; if(PreviousTrigger == null && Dependency.ControllingTriggers.Length > 0) { PreviousTrigger = Dependency.ControllingTriggers.Last(); } if(PreviousTrigger != null && !PreviousTriggers.Contains(PreviousTrigger)) { PreviousTriggers.Add(PreviousTrigger); } } // Remove previous triggers from the list that aren't the last in the chain. If there's a trigger chain of X.Y.Z, and a node has dependencies behind all three, the only trigger we care about is Z. PreviousTriggers.RemoveAll(x => PreviousTriggers.Any(y => y.ControllingTriggers.Contains(x))); // We only support one direct controlling trigger at the moment (though it may be in a chain with other triggers) if(PreviousTriggers.Count > 1) { throw new AutomationException("Node {0} has multiple controlling triggers: {1}", NodeToDo.Name, String.Join(", ", PreviousTriggers.Select(x => x.Name))); } // Update the list of controlling triggers if (PreviousTriggers.Count == 1) { List<TriggerNode> ControllingTriggers = new List<TriggerNode>(); ControllingTriggers.AddRange(PreviousTriggers[0].ControllingTriggers); ControllingTriggers.Add(PreviousTriggers[0]); NodeToDo.ControllingTriggers = ControllingTriggers.ToArray(); } } }
private List<TriggerNode> FindUnfinishedTriggers(bool bSkipTriggers, BuildNode ExplicitTrigger, List<BuildNode> OrdereredToDo) { // find all unfinished triggers, excepting the one we are triggering right now List<TriggerNode> UnfinishedTriggers = new List<TriggerNode>(); if (!bSkipTriggers) { foreach (TriggerNode NodeToDo in OrdereredToDo.OfType<TriggerNode>()) { if (!NodeToDo.IsComplete && ExplicitTrigger != NodeToDo) { UnfinishedTriggers.Add(NodeToDo); } } } return UnfinishedTriggers; }
void LogBuildFinished(BuildNode node) { List<string> messagesToReport = null; bool newNodeWithOutputLockAlreadyFinishedBuilding = false; lock (this) { if (node == nodeWithOutputLock) { if (nodesWaitingForOutputLock.Count > 0) { nodeWithOutputLock = nodesWaitingForOutputLock.Dequeue(); messagesToReport = nodeWithOutputLock.unreportedMessageList; nodeWithOutputLock.unreportedMessageList = null; newNodeWithOutputLockAlreadyFinishedBuilding = nodeWithOutputLock.buildFinished; } else { nodeWithOutputLock = null; } } } if (messagesToReport != null) { // we can report these messages outside the lock: // while they swap order with messages currently coming in (ReportMessage), // this shouldn't be a problem as nodes should not report messages after they finish building. messagesToReport.ForEach(ReportMessageInternal); } if (newNodeWithOutputLockAlreadyFinishedBuilding) { // if the node already finished building before it got the output lock, we need // to release the output lock again here LogBuildFinished(nodeWithOutputLock); } }
void ReportError(BuildNode source, BuildError error) { if (!error.IsWarning) source.hasErrors = true; results.Add(error); ReportMessage(source, error.ToString()); if (combinedBuildFeedbackSink != null) { combinedBuildFeedbackSink.ReportError(error); } }
static int CompareBuildOrder(BuildNode a, BuildNode b) { // When the build graph looks like this: // 1 2 // \ / \ // 3 4 // / \ // 5 6 // And we have 2 build workers, determining the build order alphabetically only would result // in this order: // 4, 5 // 6 // 3 // 1, 2 // However, we can build faster if we build 5+6 first: // 5, 6 // 3, 4 // 1, 2 // // As heuristic, we first build the projects that have the most projects dependent on it. int r = -(a.TotalDependentOnThisCount.CompareTo(b.TotalDependentOnThisCount)); if (r == 0) r = string.Compare(a.project.Name, b.project.Name, StringComparison.CurrentCultureIgnoreCase); return r; }
void EndOneBuild (BuildNode node) { var task = ongoing_builds [node.Build]; ongoing_builds [node.Build] = null; node.Release (); }
/// <summary> /// Builds the octree. /// </summary> #region public void BuildOctree() public void BuildOctree() { // create tri and tri bounding box arrays triBoxes = new JBBox[tris.Length]; // create an infinite size root box rootNodeBox = new JBBox(new JVector(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity), new JVector(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity)); for (int i = 0; i < tris.Length; i++) { JVector.Min(ref positions[tris[i].I1], ref positions[tris[i].I2], out triBoxes[i].Min); JVector.Min(ref positions[tris[i].I0], ref triBoxes[i].Min, out triBoxes[i].Min); JVector.Max(ref positions[tris[i].I1], ref positions[tris[i].I2], out triBoxes[i].Max); JVector.Max(ref positions[tris[i].I0], ref triBoxes[i].Max, out triBoxes[i].Max); // get size of the root box JVector.Min(ref rootNodeBox.Min, ref triBoxes[i].Min, out rootNodeBox.Min); JVector.Max(ref rootNodeBox.Max, ref triBoxes[i].Max, out rootNodeBox.Max); } List<BuildNode> buildNodes = new List<BuildNode>(); buildNodes.Add(new BuildNode()); buildNodes[0].box = rootNodeBox; JBBox[] children = new JBBox[8]; for (int triNum = 0; triNum < tris.Length; triNum++) { int nodeIndex = 0; JBBox box = rootNodeBox; while (box.Contains(ref triBoxes[triNum]) == JBBox.ContainmentType.Contains) { int childCon = -1; for (int i = 0; i < 8; ++i) { CreateAABox(ref box, (EChild)i,out children[i]); if (children[i].Contains(ref triBoxes[triNum]) == JBBox.ContainmentType.Contains) { // this box contains the tri, it can be the only one that does, // so we can stop our child search now and recurse into it childCon = i; break; } } // no child contains this tri completely, so it belong in this node if (childCon == -1) { buildNodes[nodeIndex].triIndices.Add(triNum); break; } else { // do we already have this child int childIndex = -1; for (int index = 0; index < buildNodes[nodeIndex].nodeIndices.Count; ++index) { if (buildNodes[buildNodes[nodeIndex].nodeIndices[index]].childType == childCon) { childIndex = index; break; } } if (childIndex == -1) { // nope create child BuildNode parentNode = buildNodes[nodeIndex]; BuildNode newNode = new BuildNode(); newNode.childType = childCon; newNode.box = children[childCon]; buildNodes.Add(newNode); nodeIndex = buildNodes.Count - 1; box = children[childCon]; parentNode.nodeIndices.Add(nodeIndex); } else { nodeIndex = buildNodes[nodeIndex].nodeIndices[childIndex]; box = children[childCon]; } } } } // now convert to the tighter Node from BuildNodes nodes = new Node[buildNodes.Count]; nodeStackPool = new ArrayResourcePool<ushort>(buildNodes.Count); //nodeStack = new UInt16[buildNodes.Count]; for (int i = 0; i < nodes.Length; i++) { nodes[i].nodeIndices = new UInt16[buildNodes[i].nodeIndices.Count]; for (int index = 0; index < nodes[i].nodeIndices.Length; ++index) { nodes[i].nodeIndices[index] = (UInt16)buildNodes[i].nodeIndices[index]; } nodes[i].triIndices = new int[buildNodes[i].triIndices.Count]; buildNodes[i].triIndices.CopyTo(nodes[i].triIndices); nodes[i].box = buildNodes[i].box; } buildNodes.Clear(); buildNodes = null; }
static NodeHistory FindNodeHistory(BuildNode NodeToDo, JobInfo JobInfo) { NodeHistory History = null; // Don't get node history on nodes that don't have a valid CL. if (!(NodeToDo is TriggerNode) && JobInfo.Changelist > 0) { string GameNameIfAny = NodeToDo.GameNameIfAnyForTempStorage; History = new NodeHistory { AllStarted = TempStorage.FindMatchingSharedTempStorageNodeCLs(new TempStorageNodeInfo(JobInfo, NodeToDo.Name + StartedTempStorageSuffix), GameNameIfAny), AllSucceeded = TempStorage.FindMatchingSharedTempStorageNodeCLs(new TempStorageNodeInfo(JobInfo, NodeToDo.Name + SucceededTempStorageSuffix), GameNameIfAny), AllFailed = TempStorage.FindMatchingSharedTempStorageNodeCLs(new TempStorageNodeInfo(JobInfo, NodeToDo.Name + FailedTempStorageSuffix), GameNameIfAny) }; if (History.AllFailed.Count > 0) { History.LastFailed = History.AllFailed.LastOrDefault(x => x < JobInfo.Changelist); } if (History.AllSucceeded.Count > 0) { History.LastSucceeded = History.AllSucceeded.LastOrDefault(x => x < JobInfo.Changelist); foreach (int Failed in History.AllFailed) { if (Failed > History.LastSucceeded) { History.Failed.Add(Failed); History.FailedString = GUBPNode.MergeSpaceStrings(History.FailedString, String.Format("{0}", Failed)); } } foreach (int Started in History.AllStarted) { if (Started > History.LastSucceeded && !History.Failed.Contains(Started)) { History.InProgress.Add(Started); History.InProgressString = GUBPNode.MergeSpaceStrings(History.InProgressString, String.Format("{0}", Started)); } } } } return History; }
private static void LinkNode(BuildNode Node, List<BuildNode> NodeStack, Dictionary<string, AggregateNode> NameToAggregateNode, Dictionary<string, BuildNode> NameToBuildNode, ref int NumErrors) { if(Node.OrderDependencies == null) { NodeStack.Add(Node); int NodeStackIdx = NodeStack.IndexOf(Node); if (NodeStackIdx != NodeStack.Count - 1) { // There's a cycle in the build graph. Print out the chain. CommandUtils.LogError("Build graph contains a cycle ({0})", String.Join(" -> ", NodeStack.Skip(NodeStackIdx).Select(x => x.Name))); NumErrors++; Node.OrderDependencies = new HashSet<BuildNode>(); Node.InputDependencies = new HashSet<BuildNode>(); } else { // Find all the direct input dependencies HashSet<BuildNode> DirectInputDependencies = new HashSet<BuildNode>(); foreach (string InputDependencyName in Node.InputDependencyNames) { if (!ResolveDependencies(InputDependencyName, NameToAggregateNode, NameToBuildNode, DirectInputDependencies)) { CommandUtils.LogError("Node {0} is not in the graph. It is an input dependency of {1}.", InputDependencyName, Node.Name); NumErrors++; } } // Find all the direct order dependencies. All the input dependencies are also order dependencies. HashSet<BuildNode> DirectOrderDependencies = new HashSet<BuildNode>(DirectInputDependencies); foreach (string OrderDependencyName in Node.OrderDependencyNames) { if (!ResolveDependencies(OrderDependencyName, NameToAggregateNode, NameToBuildNode, DirectOrderDependencies)) { CommandUtils.LogError("Node {0} is not in the graph. It is an order dependency of {1}.", OrderDependencyName, Node.Name); NumErrors++; } } // Link everything foreach(BuildNode DirectOrderDependency in DirectOrderDependencies) { LinkNode(DirectOrderDependency, NodeStack, NameToAggregateNode, NameToBuildNode, ref NumErrors); } // Recursively include all the input dependencies Node.InputDependencies = new HashSet<BuildNode>(DirectInputDependencies); foreach (BuildNode DirectInputDependency in DirectInputDependencies) { Node.InputDependencies.UnionWith(DirectInputDependency.InputDependencies); } // Same for the order dependencies Node.OrderDependencies = new HashSet<BuildNode>(DirectOrderDependencies); foreach (BuildNode DirectOrderDependency in DirectOrderDependencies) { Node.OrderDependencies.UnionWith(DirectOrderDependency.OrderDependencies); } } NodeStack.RemoveAt(NodeStack.Count - 1); } }
void InitializeProjectOptions(BuildNode node) { IBuildable project = node.project; // Create options for building the project node.options = project.CreateProjectBuildOptions(options, project == rootProject); }
void InitializeDependencies(BuildNode node) { // Initialize dependencies if (options.BuildDependentProjects) { var dependencies = node.project.GetBuildDependencies(node.options); if (dependencies != null) { node.dependencies = dependencies .Select<IBuildable, BuildNode>(CreateBuildGraph) .Distinct().ToArray(); } } if (node.dependencies == null) { node.dependencies = new BuildNode[0]; } node.outstandingDependencies = node.dependencies.Length; foreach (BuildNode d in node.dependencies) { if (!d.nodeComplete) throw new CyclicDependencyException(node.project, d.project); d.dependentOnThis.Add(node); } if (node.outstandingDependencies == 0) { projectsReadyForBuildStart.Add(node); } }
public BuildWorkItem(BuildNode buildNode) { BuildNode = buildNode; }
void OnBuildFinished(BuildNode node, bool success) { ICSharpCode.Core.LoggingService.Info("Finished building " + node.project.Name + ", success=" + success); node.perNodeProgressMonitor.Progress = 1; node.perNodeProgressMonitor.Dispose(); lock (this) { if (node.buildFinished) { throw new InvalidOperationException("This node already finished building, do not call IBuildFeedbackSink.Done() multiple times!"); } runningWorkers--; node.buildFinished = true; node.hasErrors = !success; projectsCurrentlyBuilding.Remove(node); results.AddBuiltProject(node.project); foreach (BuildNode n in node.dependentOnThis) { n.outstandingDependencies--; if (n.outstandingDependencies == 0) projectsReadyForBuildStart.Add(n); } workersToStart++; } LogBuildFinished(node); StartBuildProjects(); UpdateProgressTaskName(); }
public void BuildOctree( int _maxTrisPerCellNOTUSED, float _minCellSizeNOTUSED) { // create tri and tri bounding box arrays triBoxes = new BoundingBox[tris.Length]; // create an infinite size root box rootNodeBox = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity), new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity)); for (int i = 0; i < tris.Length; i++) { triBoxes[i].Min = Vector3.Min(positions[tris[i].I0], Vector3.Min(positions[tris[i].I1], positions[tris[i].I2])); triBoxes[i].Max = Vector3.Max(positions[tris[i].I0], Vector3.Max(positions[tris[i].I1], positions[tris[i].I2])); // get size of the root box rootNodeBox.Min = Vector3.Min(rootNodeBox.Min, triBoxes[i].Min); rootNodeBox.Max = Vector3.Max(rootNodeBox.Max, triBoxes[i].Max); } boundingBox = new AABox(rootNodeBox.Min, rootNodeBox.Max); List<BuildNode> buildNodes = new List<BuildNode>(); buildNodes.Add(new BuildNode()); buildNodes[0].box = rootNodeBox; BoundingBox[] children = new BoundingBox[8]; for (int triNum = 0; triNum < tris.Length; triNum++) { int nodeIndex = 0; BoundingBox box = rootNodeBox; while (box.Contains(triBoxes[triNum]) == ContainmentType.Contains) { int childCon = -1; for (int i = 0; i < 8; ++i) { children[i] = CreateAABox(box, (EChild)i); if (children[i].Contains(triBoxes[triNum]) == ContainmentType.Contains) { // this box contains the tri, it can be the only one that does, // so we can stop our child search now and recurse into it childCon = i; break; } } // no child contains this tri completely, so it belong in this node if (childCon == -1) { buildNodes[nodeIndex].triIndices.Add(triNum); break; } else { // do we already have this child int childIndex = -1; for (int index = 0; index < buildNodes[nodeIndex].nodeIndices.Count; ++index) { if (buildNodes[buildNodes[nodeIndex].nodeIndices[index]].childType == childCon) { childIndex = index; break; } } if (childIndex == -1) { // nope create child BuildNode parentNode = buildNodes[nodeIndex]; BuildNode newNode = new BuildNode(); newNode.childType = childCon; newNode.box = children[childCon]; buildNodes.Add(newNode); nodeIndex = buildNodes.Count - 1; box = children[childCon]; parentNode.nodeIndices.Add(nodeIndex); } else { nodeIndex = buildNodes[nodeIndex].nodeIndices[childIndex]; box = children[childCon]; } } } } Debug.Assert(buildNodes.Count < 0xFFFF); // now convert to the tighter Node from BuildNodes nodes = new Node[buildNodes.Count]; nodeStack = new UInt16[buildNodes.Count]; for (int i = 0; i < nodes.Length; i++) { nodes[i].nodeIndices = new UInt16[buildNodes[i].nodeIndices.Count]; for (int index = 0; index < nodes[i].nodeIndices.Length; ++index) { nodes[i].nodeIndices[index] = (UInt16)buildNodes[i].nodeIndices[index]; } nodes[i].triIndices = new int[buildNodes[i].triIndices.Count]; buildNodes[i].triIndices.CopyTo(nodes[i].triIndices); nodes[i].box = buildNodes[i].box; } buildNodes = null; }
void ReportMessage(BuildNode source, string message) { bool hasOutputLock; lock (this) { if (nodeWithOutputLock == null) { nodeWithOutputLock = source; } hasOutputLock = nodeWithOutputLock == source; if (!hasOutputLock) { if (source.unreportedMessageList == null) { nodesWaitingForOutputLock.Enqueue(source); source.unreportedMessageList = new List<string>(); } source.unreportedMessageList.Add(message); } } if (hasOutputLock) { ReportMessageInternal(message); } }
private string[] HackEmails(List<GUBPEmailHacker> EmailHackers, string Branch, BuildNode NodeInfo, out bool bIncludeCausers) { string OnlyEmail = ParseParamValue("OnlyEmail"); if (!String.IsNullOrEmpty(OnlyEmail)) { bIncludeCausers = false; return new string[]{ OnlyEmail }; } string EmailOnly = ParseParamValue("EmailOnly"); if (!String.IsNullOrEmpty(EmailOnly)) { bIncludeCausers = false; return new string[] { EmailOnly }; } string EmailHint = ParseParamValue("EmailHint"); if(EmailHint == null) { EmailHint = ""; } List<string> Result = new List<string>(); string AddEmails = ParseParamValue("AddEmails"); if (!String.IsNullOrEmpty(AddEmails)) { Result.AddRange(AddEmails.Split(new char[]{ ' ' }, StringSplitOptions.RemoveEmptyEntries)); } foreach (var EmailHacker in EmailHackers) { Result.AddRange(EmailHacker.AddEmails(this, Branch, NodeInfo.Name, EmailHint)); } foreach (var EmailHacker in EmailHackers) { var NewResult = new List<string>(); foreach (var Email in Result) { NewResult.AddRange(EmailHacker.ModifyEmail(Email, this, Branch, NodeInfo.Name)); } Result = NewResult; } bIncludeCausers = !EmailHackers.Any(x => x.VetoEmailingCausers(this, Branch, NodeInfo.Name)); return Result.ToArray(); }
int FindLastNonDuplicateFail(BuildNode NodeToDo, NodeHistory History, string CLString, string StoreName) { int Result = P4Env.Changelist; string GameNameIfAny = NodeToDo.Node.GameNameIfAnyForTempStorage(); string NodeStore = StoreName + "-" + NodeToDo.Name + FailedTempStorageSuffix; List<int> BackwardsFails = new List<int>(History.AllFailed); BackwardsFails.Add(P4Env.Changelist); BackwardsFails.Sort(); BackwardsFails.Reverse(); HashSet<string> CurrentErrors = null; foreach (int CL in BackwardsFails) { if (CL > P4Env.Changelist) { continue; } if (CL <= History.LastSucceeded) { break; } string ThisNodeStore = NodeStore.Replace(CLString, String.Format("{0}", CL)); TempStorage.DeleteLocalTempStorage(CmdEnv, ThisNodeStore, true); // these all clash locally, which is fine we just retrieve them from shared List<string> Files = null; try { bool WasLocal; Files = TempStorage.RetrieveFromTempStorage(CmdEnv, ThisNodeStore, out WasLocal, GameNameIfAny); // this will fail on our CL if we didn't fail or we are just setting up the branch } catch (Exception) { } if (Files == null) { continue; } if (Files.Count != 1) { throw new AutomationException("Unexpected number of files for fail record {0}", Files.Count); } string ErrorFile = Files[0]; HashSet<string> ThisErrors = ECJobPropsUtils.ErrorsFromProps(ErrorFile); if (CurrentErrors == null) { CurrentErrors = ThisErrors; } else { if (CurrentErrors.Count == 0 || !HashSetEqual(CurrentErrors, ThisErrors)) { break; } Result = CL; } } return Result; }
void LogBuildFinished(BuildNode node) { List<string> messagesToReport = null; bool newNodeWithOutputLockAlreadyFinishedBuilding = false; lock (this) { if (node == nodeWithOutputLock) { if (nodesWaitingForOutputLock.Count > 0) { nodeWithOutputLock = nodesWaitingForOutputLock.Dequeue(); messagesToReport = nodeWithOutputLock.unreportedMessageList; nodeWithOutputLock.unreportedMessageList = null; newNodeWithOutputLockAlreadyFinishedBuilding = nodeWithOutputLock.buildFinished; } else { nodeWithOutputLock = null; } } } if (messagesToReport != null) { messagesToReport.ForEach(ReportMessageInternal); } if (newNodeWithOutputLockAlreadyFinishedBuilding) { // if the node already finished building before it got the output lock, we need // to release the output lock again here LogBuildFinished(nodeWithOutputLock); } }
void GetFailureEmails(ElectricCommander EC, BuildNode NodeToDo, NodeHistory History, string CLString, string StoreName, bool OnlyLateUpdates = false) { string FailCauserEMails = ""; string EMailNote = ""; bool SendSuccessForGreenAfterRed = false; int NumPeople = 0; if (History != null) { if (History.LastSucceeded > 0 && History.LastSucceeded < P4Env.Changelist) { int LastNonDuplicateFail = P4Env.Changelist; try { if (OnlyLateUpdates) { LastNonDuplicateFail = FindLastNonDuplicateFail(NodeToDo, History, CLString, StoreName); if (LastNonDuplicateFail < P4Env.Changelist) { Log("*** Red-after-red spam reduction, changed CL {0} to CL {1} because the errors didn't change.", P4Env.Changelist, LastNonDuplicateFail); } } } catch (Exception Ex) { LastNonDuplicateFail = P4Env.Changelist; Log(System.Diagnostics.TraceEventType.Warning, "Failed to FindLastNonDuplicateFail."); Log(System.Diagnostics.TraceEventType.Warning, LogUtils.FormatException(Ex)); } if(LastNonDuplicateFail > History.LastSucceeded) { List<P4Connection.ChangeRecord> ChangeRecords = GetSourceChangeRecords(History.LastSucceeded + 1, LastNonDuplicateFail); foreach (P4Connection.ChangeRecord Record in ChangeRecords) { FailCauserEMails = GUBPNode.MergeSpaceStrings(FailCauserEMails, Record.UserEmail); } } if (!String.IsNullOrEmpty(FailCauserEMails)) { NumPeople++; foreach (char AChar in FailCauserEMails.ToCharArray()) { if (AChar == ' ') { NumPeople++; } } if (NumPeople > 50) { EMailNote = String.Format("This step has been broken for more than 50 changes. It last succeeded at CL {0}. ", History.LastSucceeded); } } } else if (History.LastSucceeded <= 0) { EMailNote = String.Format("This step has been broken for more than a few days, so there is no record of it ever succeeding. "); } if (EMailNote != "" && !String.IsNullOrEmpty(History.FailedString)) { EMailNote += String.Format("It has failed at CLs {0}. ", History.FailedString); } if (EMailNote != "" && !String.IsNullOrEmpty(History.InProgressString)) { EMailNote += String.Format("These CLs are being built right now {0}. ", History.InProgressString); } if (History.LastSucceeded > 0 && History.LastSucceeded < P4Env.Changelist && History.LastFailed > History.LastSucceeded && History.LastFailed < P4Env.Changelist) { SendSuccessForGreenAfterRed = ParseParam("CIS"); } } if (History == null) { EC.UpdateEmailProperties(NodeToDo, 0, "", FailCauserEMails, EMailNote, SendSuccessForGreenAfterRed); } else { EC.UpdateEmailProperties(NodeToDo, History.LastSucceeded, History.FailedString, FailCauserEMails, EMailNote, SendSuccessForGreenAfterRed); } }
static void VisitDependentOnThis(HashSet<BuildNode> visitedNodes, BuildNode node) { if (visitedNodes.Add(node)) { foreach (BuildNode n in node.dependentOnThis) { VisitDependentOnThis(visitedNodes, n); } } }
static NodeHistory FindNodeHistory(BuildNode NodeToDo, string CLString, string StoreName) { NodeHistory History = null; if (!(NodeToDo is TriggerNode) && CLString != "") { string GameNameIfAny = NodeToDo.Node.GameNameIfAnyForTempStorage(); string NodeStoreWildCard = StoreName.Replace(CLString, "*") + "-" + NodeToDo.Name; History = new NodeHistory(); History.AllStarted = ConvertCLToIntList(TempStorage.FindTempStorageManifests(CmdEnv, NodeStoreWildCard + StartedTempStorageSuffix, false, true, GameNameIfAny)); History.AllSucceeded = ConvertCLToIntList(TempStorage.FindTempStorageManifests(CmdEnv, NodeStoreWildCard + SucceededTempStorageSuffix, false, true, GameNameIfAny)); History.AllFailed = ConvertCLToIntList(TempStorage.FindTempStorageManifests(CmdEnv, NodeStoreWildCard + FailedTempStorageSuffix, false, true, GameNameIfAny)); int CL; int.TryParse(CLString, out CL); if (History.AllFailed.Count > 0) { History.LastFailed = History.AllFailed.LastOrDefault(x => x < CL); } if (History.AllSucceeded.Count > 0) { History.LastSucceeded = History.AllSucceeded.LastOrDefault(x => x < CL); foreach (int Failed in History.AllFailed) { if (Failed > History.LastSucceeded) { History.Failed.Add(Failed); History.FailedString = GUBPNode.MergeSpaceStrings(History.FailedString, String.Format("{0}", Failed)); } } foreach (int Started in History.AllStarted) { if (Started > History.LastSucceeded && !History.Failed.Contains(Started)) { History.InProgress.Add(Started); History.InProgressString = GUBPNode.MergeSpaceStrings(History.InProgressString, String.Format("{0}", Started)); } } } } return History; }
BuildNode CreateBuildGraph(IBuildable project) { BuildNode node; if (nodeDict.TryGetValue(project, out node)) { return node; } node = new BuildNode(this, project); nodeDict[project] = node; InitializeProjectOptions(node); InitializeDependencies(node); node.nodeComplete = true; return node; }
static List<BuildNode> TopologicalSort(HashSet<BuildNode> NodesToDo, BuildNode ExplicitTrigger, bool SubSort, bool DoNotConsiderCompletion) { DateTime StartTime = DateTime.UtcNow; List<BuildNode> OrdereredToDo = new List<BuildNode>(); Dictionary<string, List<BuildNode>> SortedAgentGroupChains = new Dictionary<string, List<BuildNode>>(); if (!SubSort) { Dictionary<string, List<BuildNode>> AgentGroupChains = new Dictionary<string, List<BuildNode>>(); foreach (BuildNode NodeToDo in NodesToDo) { string MyAgentGroup = NodeToDo.AgentSharingGroup; if (MyAgentGroup != "") { if (!AgentGroupChains.ContainsKey(MyAgentGroup)) { AgentGroupChains.Add(MyAgentGroup, new List<BuildNode> { NodeToDo }); } else { AgentGroupChains[MyAgentGroup].Add(NodeToDo); } } } foreach (KeyValuePair<string, List<BuildNode>> Chain in AgentGroupChains) { SortedAgentGroupChains.Add(Chain.Key, TopologicalSort(new HashSet<BuildNode>(Chain.Value), ExplicitTrigger, true, DoNotConsiderCompletion)); } foreach(KeyValuePair<string, List<BuildNode>> Chain in SortedAgentGroupChains) { string[] ControllingTriggers = Chain.Value.Select(x => x.ControllingTriggerDotName).Distinct().OrderBy(x => x).ToArray(); if(ControllingTriggers.Length > 1) { string Triggers = String.Join(", ", ControllingTriggers.Select(x => String.Format("'{0}' ({1})", x, String.Join("+", Chain.Value.Where(y => y.ControllingTriggerDotName == x).Select(y => y.Name))))); throw new AutomationException("Agent sharing group '{0}' has multiple controlling triggers: {1}", Chain.Key, Triggers); } } Log("***************Done with recursion"); } // here we do a topological sort of the nodes, subject to a lexographical and priority sort while (NodesToDo.Count > 0) { bool bProgressMade = false; float BestPriority = -1E20f; BuildNode BestNode = null; bool BestPseudoReady = false; HashSet<string> NonReadyAgentGroups = new HashSet<string>(); HashSet<string> NonPeudoReadyAgentGroups = new HashSet<string>(); HashSet<string> ExaminedAgentGroups = new HashSet<string>(); foreach (BuildNode NodeToDo in NodesToDo) { bool bReady = true; bool bPseudoReady = true; bool bCompReady = true; if (!SubSort && NodeToDo.AgentSharingGroup != "") { if (ExaminedAgentGroups.Contains(NodeToDo.AgentSharingGroup)) { bReady = !NonReadyAgentGroups.Contains(NodeToDo.AgentSharingGroup); bPseudoReady = !NonPeudoReadyAgentGroups.Contains(NodeToDo.AgentSharingGroup); //this might not be accurate if bReady==false } else { ExaminedAgentGroups.Add(NodeToDo.AgentSharingGroup); foreach (BuildNode ChainNode in SortedAgentGroupChains[NodeToDo.AgentSharingGroup]) { foreach (BuildNode Dep in ChainNode.Dependencies) { if (!SortedAgentGroupChains[NodeToDo.AgentSharingGroup].Contains(Dep) && NodesToDo.Contains(Dep)) { bReady = false; break; } } if (!bReady) { NonReadyAgentGroups.Add(NodeToDo.AgentSharingGroup); break; } foreach (BuildNode Dep in ChainNode.PseudoDependencies) { if (!SortedAgentGroupChains[NodeToDo.AgentSharingGroup].Contains(Dep) && NodesToDo.Contains(Dep)) { bPseudoReady = false; NonPeudoReadyAgentGroups.Add(NodeToDo.AgentSharingGroup); break; } } } } } else { foreach (BuildNode Dep in NodeToDo.Dependencies) { if (NodesToDo.Contains(Dep)) { bReady = false; break; } } foreach (BuildNode Dep in NodeToDo.PseudoDependencies) { if (NodesToDo.Contains(Dep)) { bPseudoReady = false; break; } } } float Priority = NodeToDo.Priority; if (bReady && BestNode != null) { if (String.Compare(BestNode.ControllingTriggerDotName, NodeToDo.ControllingTriggerDotName) < 0) //sorted by controlling trigger { bReady = false; } else if (String.Compare(BestNode.ControllingTriggerDotName, NodeToDo.ControllingTriggerDotName) == 0) //sorted by controlling trigger { if (BestNode.IsSticky && !NodeToDo.IsSticky) //sticky nodes first { bReady = false; } else if (BestNode.IsSticky == NodeToDo.IsSticky) { if (BestPseudoReady && !bPseudoReady) { bReady = false; } else if (BestPseudoReady == bPseudoReady) { bool IamLateTrigger = !DoNotConsiderCompletion && (NodeToDo is TriggerNode) && NodeToDo != ExplicitTrigger && !NodeToDo.IsComplete; bool BestIsLateTrigger = !DoNotConsiderCompletion && (BestNode is TriggerNode) && BestNode != ExplicitTrigger && !BestNode.IsComplete; if (BestIsLateTrigger && !IamLateTrigger) { bReady = false; } else if (BestIsLateTrigger == IamLateTrigger) { if (Priority < BestPriority) { bReady = false; } else if (Priority == BestPriority) { if (BestNode.Name.CompareTo(NodeToDo.Name) < 0) { bReady = false; } } if (!bCompReady) { bReady = false; } } } } } } if (bReady) { BestPriority = Priority; BestNode = NodeToDo; BestPseudoReady = bPseudoReady; bProgressMade = true; } } if (bProgressMade) { if (!SubSort && BestNode.AgentSharingGroup != "") { foreach (BuildNode ChainNode in SortedAgentGroupChains[BestNode.AgentSharingGroup]) { OrdereredToDo.Add(ChainNode); NodesToDo.Remove(ChainNode); } } else { OrdereredToDo.Add(BestNode); NodesToDo.Remove(BestNode); } } if (!bProgressMade && NodesToDo.Count > 0) { Log("Cycle in GUBP, could not resolve:"); foreach (BuildNode NodeToDo in NodesToDo) { string Deps = ""; if (!SubSort && NodeToDo.AgentSharingGroup != "") { foreach (BuildNode ChainNode in SortedAgentGroupChains[NodeToDo.AgentSharingGroup]) { foreach (BuildNode Dep in ChainNode.Dependencies) { if (!SortedAgentGroupChains[NodeToDo.AgentSharingGroup].Contains(Dep) && NodesToDo.Contains(Dep)) { Deps = Deps + Dep.Name + "[" + ChainNode.Name + "->" + NodeToDo.AgentSharingGroup + "]" + " "; } } } } foreach (BuildNode Dep in NodeToDo.Dependencies) { if (NodesToDo.Contains(Dep)) { Deps = Deps + Dep.Name + " "; } } foreach (BuildNode Dep in NodeToDo.PseudoDependencies) { if (NodesToDo.Contains(Dep)) { Deps = Deps + Dep.Name + " "; } } Log(" {0} deps: {1}", NodeToDo.Name, Deps); } throw new AutomationException("Cycle in GUBP"); } } if (!SubSort) { double BuildDuration = (DateTime.UtcNow - StartTime).TotalMilliseconds; Log("Took {0}s to sort {1} nodes", BuildDuration / 1000, OrdereredToDo.Count); } return OrdereredToDo; }
// FIXME: take max nodes into account here, and get throttling working. BuildNode TakeNode (BuildSubmission build) { var host = BuildManager.OngoingBuildParameters.HostServices; NodeAffinity affinity; if (host == null) affinity = NodeAffinity.Any; else affinity = host.GetNodeAffinity (build.BuildRequest.ProjectFullPath); BuildNode n = GetReusableNode (affinity); if (n != null) n.Assign (build); else { n = new BuildNode (this, affinity == NodeAffinity.Any ? NodeAffinity.InProc : affinity); n.Assign (build); if (n.Affinity == NodeAffinity.InProc) in_proc_nodes.Add (n); else out_proc_nodes.Add (n); } return n; }