////private DbgVerbCounter dbgVerbCounter = new DbgVerbCounter(); /// <summary> /// Initializes a new instance of the Scheduler class. /// </summary> /// <param name="jobParallelism"> /// Degree of parallel execution to allow. /// </param> /// <param name="rejectCachedFailures"> /// Whether to reject cached failures. /// </param> public Scheduler(int jobParallelism) { this.targets = new HashSet <BuildObject>(); this.waitIndex = new WaitIndex(); this.repository = BuildEngine.theEngine.Repository; this.unrecordableFailures = new Dictionary <IVerb, Disposition>(); this.verbToposorter = new VerbToposorter(); this.verbRunner = new VerbRunner(this.verbToposorter, jobParallelism); this.resolvedVerbs = new HashSet <IVerb>(); this.completedVerbs = new HashSet <IVerb>(); this.outputToVerbMap = new Dictionary <BuildObject, IVerb>(); this.knownVerbs = new HashSet <IVerb>(); this.depCache = new DependencyCache(); this.rejectCachedFailures = true; // this is now permanent. The code path for caching Failure results has rotted. }
/// <summary> /// Initializes a new instance of the AsyncVerbTask class. /// </summary> /// <param name="runner"> /// The verb running part of the scheduler. /// </param> /// <param name="worker"> /// The worker of this verb task. /// </param> /// <param name="verb"> /// The verb associated with this task/worker. /// </param> public AsyncVerbTask(VerbRunner runner, IVerbWorker worker, IVerb verb) { this.runner = runner; this.worker = worker; this.verb = verb; }
/// <summary> /// Record how each output of a task appeared. /// </summary> /// <param name="completion">The task completion notification.</param> /// <returns>Overall result of the verb execution.</returns> private Disposition recordResult(VerbRunner.TaskCompletion completion) { WorkingDirectory workingDirectory = completion.workingDirectory; IVerb verb = completion.verb; Disposition executionDisposition = completion.disposition; List<BuildObjectValuePointer> outputs = new List<BuildObjectValuePointer>(); List<string> missingOutputs = new List<string>(); IEnumerable<BuildObject> expectedOutputs = verb.getOutputs(); if (executionDisposition is Failed) { expectedOutputs = expectedOutputs.Concat(verb.getFailureOutputs()); } bool hasVirtualOutputs = false; foreach (BuildObject outobj in expectedOutputs) { if (!(outobj is VirtualBuildObject)) { // For expected file outputs, check for existence in working directory. // REVIEW: Add method to WorkingDirectory which does this? if (File.Exists(workingDirectory.PathTo(outobj))) { // Try to catch accidental case mismatches that would burn us when we // try to fetch the file back in. ////string fsname = PathNormalizer.dbg_normalizePath_nocache(outobj.deprecatedGetFilesystemPath(), false); ////Util.Assert(Path.GetFileName(fsname).Equals(outobj.getFileName())); // REVIEW: Do we need to worry about case mismatches anymore? See comments above. outputs.Add(this.repository.Store(workingDirectory, outobj, executionDisposition)); // Store a copy of this verb output as a file in the real nuobj directory. Util.Assert(outobj.getRelativePath().StartsWith(BuildEngine.theEngine.getObjRoot(), StringComparison.Ordinal)); string nuobjPath = IronRootDirectory.PathTo(outobj); Directory.CreateDirectory(Path.GetDirectoryName(nuobjPath)); File.Copy(workingDirectory.PathTo(outobj), nuobjPath, true); } else { missingOutputs.Add(string.Format("Missing expected output {0}", outobj.getRelativePath())); } } else { hasVirtualOutputs = true; if (this.repository.GetDisposition(outobj) is Fresh) { // Nothing to cache; virtual objects only survive in the Repository, the in-process store. } else { missingOutputs.Add(string.Format("Missing expected virtual {0}", outobj.getRelativePath())); } } } if (!(executionDisposition is Failed) && missingOutputs.Count() > 0) { executionDisposition = new Failed(missingOutputs); } ResultSummaryRecord summary = new ResultSummaryRecord(verb, executionDisposition, outputs); string inputHash = this.computeInputHash(verb, true); Util.Assert(inputHash != null); if (!hasVirtualOutputs) { this.repository.StoreResult(inputHash, summary); } else { this.Say("Not caching verb persistently: " + verb); } this.verbIsComplete(verb, executionDisposition); return executionDisposition; }
////private DbgVerbCounter dbgVerbCounter = new DbgVerbCounter(); /// <summary> /// Initializes a new instance of the Scheduler class. /// </summary> /// <param name="jobParallelism"> /// Degree of parallel execution to allow. /// </param> /// <param name="rejectCachedFailures"> /// Whether to reject cached failures. /// </param> public Scheduler(int jobParallelism) { this.targets = new HashSet<BuildObject>(); this.waitIndex = new WaitIndex(); this.repository = BuildEngine.theEngine.Repository; this.unrecordableFailures = new Dictionary<IVerb, Disposition>(); this.verbToposorter = new VerbToposorter(); this.verbRunner = new VerbRunner(this.verbToposorter, jobParallelism); this.resolvedVerbs = new HashSet<IVerb>(); this.completedVerbs = new HashSet<IVerb>(); this.outputToVerbMap = new Dictionary<BuildObject, IVerb>(); this.knownVerbs = new HashSet<IVerb>(); this.depCache = new DependencyCache(); this.rejectCachedFailures = true; // this is now permanent. The code path for caching Failure results has rotted. }