/// <summary> /// Handles the NodeConfiguration packet. /// </summary> private void HandleNodeConfiguration(NodeConfiguration configuration) { // Set the culture. #if FEATURE_CULTUREINFO_SETTERS CultureInfo.CurrentCulture = configuration.BuildParameters.Culture; CultureInfo.CurrentUICulture = configuration.BuildParameters.UICulture; #else Thread.CurrentThread.CurrentCulture = configuration.BuildParameters.Culture; Thread.CurrentThread.CurrentUICulture = configuration.BuildParameters.UICulture; #endif // Snapshot the initial environment. _savedEnvironment = CommunicationsUtilities.GetEnvironmentVariables(); // Save the current directory. _savedCurrentDirectory = NativeMethodsShared.GetCurrentDirectory(); // Set the node id. _componentHost.BuildParameters.NodeId = configuration.NodeId; _shutdownException = null; #if FEATURE_APPDOMAIN // And the AppDomainSetup _componentHost.BuildParameters.AppDomainSetup = configuration.AppDomainSetup; #endif // Declare in-proc _componentHost.BuildParameters.IsOutOfProc = false; // Set the logging exception handler ILoggingService loggingService = _componentHost.LoggingService; loggingService.OnLoggingThreadException += new LoggingExceptionDelegate(OnLoggingThreadException); // Now prep the buildRequestEngine for the build. _loggingContext = new NodeLoggingContext(loggingService, configuration.NodeId, true /* inProcNode */); _buildRequestEngine.OnEngineException += _engineExceptionEventHandler; _buildRequestEngine.OnNewConfigurationRequest += _newConfigurationRequestEventHandler; _buildRequestEngine.OnRequestBlocked += _requestBlockedEventHandler; _buildRequestEngine.OnRequestComplete += _requestCompleteEventHandler; if (_shutdownException != null) { Exception exception; HandleShutdown(out exception); throw exception; } _buildRequestEngine.InitializeForBuild(_loggingContext); // Finally store off this configuration packet. _currentConfiguration = configuration; }
/// <summary> /// Build a request entry /// </summary> /// <param name="entry"></param> public void BuildRequest(NodeLoggingContext nodeLoggingContext, BuildRequestEntry entry) { this.requestedEntry = entry; if (null == this.requestedEntry.RequestConfiguration.Project) { Project mockProject = new Project(XmlReader.Create(new System.IO.StringReader( @"<Project ToolsVersion='4.0' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'> <Target Name='t'> </Target> </Project>"))); this.requestedEntry.RequestConfiguration.Project = mockProject.CreateProjectInstance(); } this.currentProjectDefinition = this.testDataProvider[this.requestedEntry.Request.ConfigurationId]; this.requestedEntry.Continue(); this.builderThread = new Thread(BuilderThreadProc); this.builderThread.Name = "Builder Thread for Request: " + entry.Request.ConfigurationId.ToString(); this.builderThread.Start(); }
/// <summary> /// Perform necessary actions to shut down the node. /// </summary> private NodeEngineShutdownReason HandleShutdown(out Exception exception) { // Console.WriteLine("Node shutting down with reason {0} and exception: {1}", shutdownReason, shutdownException); try { // Clean up the engine if (_buildRequestEngine != null && _buildRequestEngine.Status != BuildRequestEngineStatus.Uninitialized) { _buildRequestEngine.CleanupForBuild(); } } catch (Exception ex) { if (ExceptionHandling.IsCriticalException(ex)) { throw; } // If we had some issue shutting down, don't reuse the node because we may be in some weird state. if (_shutdownReason == NodeEngineShutdownReason.BuildCompleteReuse) { _shutdownReason = NodeEngineShutdownReason.BuildComplete; } } // Dispose of any build registered objects IRegisteredTaskObjectCache objectCache = (IRegisteredTaskObjectCache)(_componentHost.GetComponent(BuildComponentType.RegisteredTaskObjectCache)); objectCache.DisposeCacheObjects(RegisteredTaskObjectLifetime.Build); if (_shutdownReason != NodeEngineShutdownReason.BuildCompleteReuse) { // Dispose of any node registered objects. ((IBuildComponent)objectCache).ShutdownComponent(); } if (_componentHost.BuildParameters.SaveOperatingEnvironment) { // Restore the original current directory. NativeMethodsShared.SetCurrentDirectory(_savedCurrentDirectory); // Restore the original environment. foreach (KeyValuePair <string, string> entry in CommunicationsUtilities.GetEnvironmentVariables()) { if (!_savedEnvironment.ContainsKey(entry.Key)) { Environment.SetEnvironmentVariable(entry.Key, null); } } foreach (KeyValuePair <string, string> entry in _savedEnvironment) { Environment.SetEnvironmentVariable(entry.Key, entry.Value); } } exception = _shutdownException; if (_loggingContext != null) { _loggingContext.LoggingService.OnLoggingThreadException -= OnLoggingThreadException; _loggingContext = null; } // Notify the BuildManager that we are done. if (_nodeEndpoint.LinkStatus == LinkStatus.Active) { _nodeEndpoint.SendData(new NodeShutdown(_shutdownReason == NodeEngineShutdownReason.Error ? NodeShutdownReason.Error : NodeShutdownReason.Requested, exception)); } _buildRequestEngine.OnEngineException -= _engineExceptionEventHandler; _buildRequestEngine.OnNewConfigurationRequest -= _newConfigurationRequestEventHandler; _buildRequestEngine.OnRequestBlocked -= _requestBlockedEventHandler; _buildRequestEngine.OnRequestComplete -= _requestCompleteEventHandler; _buildRequestEngine.OnResourceRequest -= _resourceRequestHandler; return(_shutdownReason); }
/// <summary> /// Build a request entry /// </summary> /// <param name="entry"></param> public void BuildRequest(NodeLoggingContext nodeLoggingContext, BuildRequestEntry entry) { _requestedEntry = entry; if (null == _requestedEntry.RequestConfiguration.Project) { Project mockProject = new Project(XmlReader.Create(new System.IO.StringReader( @"<Project ToolsVersion='4.0' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'> <Target Name='t'> </Target> </Project>"))); _requestedEntry.RequestConfiguration.Project = mockProject.CreateProjectInstance(); } _currentProjectDefinition = _testDataProvider[_requestedEntry.Request.ConfigurationId]; _requestedEntry.Continue(); _builderThread = new Thread(BuilderThreadProc); _builderThread.Name = "Builder Thread for Request: " + entry.Request.ConfigurationId.ToString(); _builderThread.Start(); }
/// <summary> /// Logs the project started/finished pair for projects which are skipped entirely because all /// of their results are available in the cache. /// </summary> private void LogRequestHandledFromCache(BuildRequest request, BuildResult result) { BuildRequestConfiguration configuration = _configCache[request.ConfigurationId]; int nodeId = _schedulingData.GetAssignedNodeForRequestConfiguration(request.ConfigurationId); NodeLoggingContext nodeContext = new NodeLoggingContext(_componentHost.LoggingService, nodeId, true); nodeContext.LogRequestHandledFromCache(request, configuration, result); }
private static IntrinsicTask CreateIntrinsicTask(string content) { Project project = new Project(XmlReader.Create(new StringReader(content))); ProjectInstance projectInstance = project.CreateProjectInstance(); ProjectTargetInstanceChild targetChild = projectInstance.Targets["t"].Children.First(); NodeLoggingContext nodeContext = new NodeLoggingContext(new MockLoggingService(), 1, false); BuildRequestEntry entry = new BuildRequestEntry(new BuildRequest(1 /* submissionId */, 0, 1, new string[] { "t" }, null, BuildEventContext.Invalid, null), new BuildRequestConfiguration(1, new BuildRequestData("projectFile", new Dictionary<string, string>(), "3.5", new string[0], null), "2.0")); entry.RequestConfiguration.Project = projectInstance; IntrinsicTask task = IntrinsicTask.InstantiateTask( targetChild, nodeContext.LogProjectStarted(entry).LogTargetBatchStarted(projectInstance.FullPath, projectInstance.Targets["t"], null), projectInstance, false); return task; }
/// <summary> /// Handles the NodeConfiguration packet. /// </summary> private void HandleNodeConfiguration(NodeConfiguration configuration) { // Set the culture. Thread.CurrentThread.CurrentCulture = configuration.BuildParameters.Culture; Thread.CurrentThread.CurrentUICulture = configuration.BuildParameters.UICulture; // Snapshot the initial environment. _savedEnvironment = CommunicationsUtilities.GetEnvironmentVariables(); // Save the current directory. _savedCurrentDirectory = NativeMethodsShared.GetCurrentDirectory(); // Set the node id. _componentHost.BuildParameters.NodeId = configuration.NodeId; _shutdownException = null; // And the AppDomainSetup _componentHost.BuildParameters.AppDomainSetup = configuration.AppDomainSetup; // Declare in-proc _componentHost.BuildParameters.IsOutOfProc = false; // Set the logging exception handler ILoggingService loggingService = _componentHost.LoggingService; loggingService.OnLoggingThreadException += new LoggingExceptionDelegate(OnLoggingThreadException); // Now prep the buildRequestEngine for the build. _loggingContext = new NodeLoggingContext(loggingService, configuration.NodeId, true /* inProcNode */); _buildRequestEngine.OnEngineException += _engineExceptionEventHandler; _buildRequestEngine.OnNewConfigurationRequest += _newConfigurationRequestEventHandler; _buildRequestEngine.OnRequestBlocked += _requestBlockedEventHandler; _buildRequestEngine.OnRequestComplete += _requestCompleteEventHandler; if (_shutdownException != null) { Exception exception; HandleShutdown(out exception); throw exception; } _buildRequestEngine.InitializeForBuild(_loggingContext); // Finally store off this configuration packet. _currentConfiguration = configuration; }
/// <summary> /// Perform necessary actions to shut down the node. /// </summary> private NodeEngineShutdownReason HandleShutdown(out Exception exception) { // Console.WriteLine("Node shutting down with reason {0} and exception: {1}", shutdownReason, shutdownException); try { // Clean up the engine if (null != _buildRequestEngine && _buildRequestEngine.Status != BuildRequestEngineStatus.Uninitialized) { _buildRequestEngine.CleanupForBuild(); } } catch (Exception ex) { if (ExceptionHandling.IsCriticalException(ex)) { throw; } // If we had some issue shutting down, don't reuse the node because we may be in some weird state. if (_shutdownReason == NodeEngineShutdownReason.BuildCompleteReuse) { _shutdownReason = NodeEngineShutdownReason.BuildComplete; } } // Dispose of any build registered objects IRegisteredTaskObjectCache objectCache = (IRegisteredTaskObjectCache)(_componentHost.GetComponent(BuildComponentType.RegisteredTaskObjectCache)); objectCache.DisposeCacheObjects(RegisteredTaskObjectLifetime.Build); if (_shutdownReason != NodeEngineShutdownReason.BuildCompleteReuse) { // Dispose of any node registered objects. ((IBuildComponent)objectCache).ShutdownComponent(); } if (_componentHost.BuildParameters.SaveOperatingEnvironment) { // Restore the original current directory. NativeMethodsShared.SetCurrentDirectory(_savedCurrentDirectory); // Restore the original environment. foreach (KeyValuePair<string, string> entry in CommunicationsUtilities.GetEnvironmentVariables()) { if (!_savedEnvironment.ContainsKey(entry.Key)) { Environment.SetEnvironmentVariable(entry.Key, null); } } foreach (KeyValuePair<string, string> entry in _savedEnvironment) { Environment.SetEnvironmentVariable(entry.Key, entry.Value); } } exception = _shutdownException; if (null != _loggingContext) { _loggingContext.LoggingService.OnLoggingThreadException -= new LoggingExceptionDelegate(OnLoggingThreadException); _loggingContext = null; } // Notify the BuildManager that we are done. if (_nodeEndpoint.LinkStatus == LinkStatus.Active) { _nodeEndpoint.SendData(new NodeShutdown(_shutdownReason == NodeEngineShutdownReason.Error ? NodeShutdownReason.Error : NodeShutdownReason.Requested, exception)); } _buildRequestEngine.OnEngineException -= _engineExceptionEventHandler; _buildRequestEngine.OnNewConfigurationRequest -= _newConfigurationRequestEventHandler; _buildRequestEngine.OnRequestBlocked -= _requestBlockedEventHandler; _buildRequestEngine.OnRequestComplete -= _requestCompleteEventHandler; return _shutdownReason; }
/// <summary> /// Reports this result to the engine and cleans up. /// </summary> private void ReportResultAndCleanUp(BuildResult result) { if (null != _projectLoggingContext) { try { _projectLoggingContext.LogProjectFinished(result.OverallResult == BuildResultCode.Success); } catch (Exception ex) { if (ExceptionHandling.IsCriticalException(ex)) { throw; } if (result.Exception == null) { result.Exception = ex; } } } // Clear out our state now in case any of these callbacks cause the engine to try and immediately // reuse this builder. BuildRequestEntry entryToComplete = _requestEntry; _nodeLoggingContext = null; _requestEntry = null; if (_targetBuilder != null) { ((IBuildComponent)_targetBuilder).ShutdownComponent(); } if (_componentHost.BuildParameters.SaveOperatingEnvironment) { entryToComplete.RequestConfiguration.SavedCurrentDirectory = NativeMethodsShared.GetCurrentDirectory(); entryToComplete.RequestConfiguration.SavedEnvironmentVariables = CommunicationsUtilities.GetEnvironmentVariables(); } entryToComplete.Complete(result); RaiseBuildRequestCompleted(entryToComplete); }
/// <summary> /// Starts a build request /// </summary> /// <param name="loggingContext">The logging context for the node.</param> /// <param name="entry">The entry to build.</param> public void BuildRequest(NodeLoggingContext loggingContext, BuildRequestEntry entry) { ErrorUtilities.VerifyThrowArgumentNull(loggingContext, "loggingContext"); ErrorUtilities.VerifyThrowArgumentNull(entry, "entry"); ErrorUtilities.VerifyThrow(null != _componentHost, "Host not set."); ErrorUtilities.VerifyThrow(_targetBuilder == null, "targetBuilder not null"); ErrorUtilities.VerifyThrow(_nodeLoggingContext == null, "nodeLoggingContext not null"); ErrorUtilities.VerifyThrow(_requestEntry == null, "requestEntry not null"); ErrorUtilities.VerifyThrow(!_terminateEvent.WaitOne(0), "Cancel already called"); _nodeLoggingContext = loggingContext; _blockType = BlockType.Unblocked; _requestEntry = entry; _requestEntry.Continue(); _continueResults = null; _targetBuilder = (ITargetBuilder)_componentHost.GetComponent(BuildComponentType.TargetBuilder); VerifyEntryInActiveState(); InitializeOperatingEnvironment(); StartBuilderThread(); }