public TaskHostTask(IElementLocation taskLocation, TaskLoggingContext taskLoggingContext, IBuildComponentHost buildComponentHost, IDictionary <string, string> taskHostParameters, LoadedType taskType #if FEATURE_APPDOMAIN , AppDomainSetup appDomainSetup #endif ) { ErrorUtilities.VerifyThrowInternalNull(taskType, nameof(taskType)); _taskLocation = taskLocation; _taskLoggingContext = taskLoggingContext; _buildComponentHost = buildComponentHost; _taskType = taskType; #if FEATURE_APPDOMAIN _appDomainSetup = appDomainSetup; #endif _taskHostParameters = taskHostParameters; _packetFactory = new NodePacketFactory(); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.LogMessage, LogMessagePacket.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.TaskHostTaskComplete, TaskHostTaskComplete.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.NodeShutdown, NodeShutdown.FactoryForDeserialization, this); _packetReceivedEvent = new AutoResetEvent(false); _receivedPackets = new ConcurrentQueue <INodePacket>(); _taskHostLock = new Object(); _setParameters = new Dictionary <string, object>(); }
/// <summary> /// Shuts down all of the managed nodes permanently. /// </summary> /// <param name="hostHandshake">host handshake key</param> /// <param name="clientHandshake">client handshake key</param> /// <param name="terminateNode">Delegate used to tell the node provider that a context has terminated</param> protected void ShutdownAllNodes(long hostHandshake, long clientHandshake, NodeContextTerminateDelegate terminateNode) { #if FEATURE_NAMED_PIPES_FULL_DUPLEX // INodePacketFactory INodePacketFactory factory = new NodePacketFactory(); List <Process> nodeProcesses = GetPossibleRunningNodes(); // Find proper MSBuildTaskHost executable name string msbuildtaskhostExeName = NodeProviderOutOfProcTaskHost.TaskHostNameForClr2TaskHost; // Search for all instances of msbuildtaskhost process and add them to the process list nodeProcesses.AddRange(new List <Process>(Process.GetProcessesByName(Path.GetFileNameWithoutExtension(msbuildtaskhostExeName)))); // For all processes in the list, send signal to terminate if able to connect foreach (Process nodeProcess in nodeProcesses) { Stream nodeStream = TryConnectToProcess(nodeProcess.Id, 30 /*verified to miss nodes if smaller*/, hostHandshake, clientHandshake); if (null != nodeStream) { // If we're able to connect to such a process, send a packet requesting its termination CommunicationsUtilities.Trace("Shutting down node with pid = {0}", nodeProcess.Id); NodeContext nodeContext = new NodeContext(0, nodeProcess.Id, nodeStream, factory, terminateNode); nodeContext.SendData(new NodeBuildComplete(false /* no node reuse */)); nodeStream.Dispose(); } } #else throw new PlatformNotSupportedException("Shutting down nodes by enumerating processes and connecting to them is not supported when using anonymous pipes."); #endif }
public void ClearPerBuildState() { _packetFactory = new NodePacketFactory(); _nodeIdToProvider.Clear(); // because the inproc node is always 1 therefore when new nodes are requested we need to start at 2 _nextNodeId = _inprocNodeId + 1; }
/// <summary> /// Initializes the component. /// </summary> /// <param name="host">The component host.</param> public void InitializeComponent(IBuildComponentHost host) { this.ComponentHost = host; _nodeContexts = new Dictionary <TaskHostContext, NodeContext>(); _nodeIdToPacketFactory = new Dictionary <int, INodePacketFactory>(); _nodeIdToPacketHandler = new Dictionary <int, INodePacketHandler>(); _activeNodes = new HashSet <int>(); _noNodesActiveEvent = new ManualResetEvent(true); _localPacketFactory = new NodePacketFactory(); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.LogMessage, LogMessagePacket.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.TaskHostTaskComplete, TaskHostTaskComplete.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.NodeShutdown, NodeShutdown.FactoryForDeserialization, this); }
/// <summary> /// Shuts down all of the managed nodes permanently. /// </summary> /// <param name="nodeReuse">Whether to reuse the node</param> /// <param name="terminateNode">Delegate used to tell the node provider that a context has terminated</param> protected void ShutdownAllNodes(bool nodeReuse, NodeContextTerminateDelegate terminateNode) { // INodePacketFactory INodePacketFactory factory = new NodePacketFactory(); List <Process> nodeProcesses = GetPossibleRunningNodes().nodeProcesses; // Find proper MSBuildTaskHost executable name string msbuildtaskhostExeName = NodeProviderOutOfProcTaskHost.TaskHostNameForClr2TaskHost; // Search for all instances of msbuildtaskhost process and add them to the process list nodeProcesses.AddRange(new List <Process>(Process.GetProcessesByName(Path.GetFileNameWithoutExtension(msbuildtaskhostExeName)))); // For all processes in the list, send signal to terminate if able to connect foreach (Process nodeProcess in nodeProcesses) { // A 2013 comment suggested some nodes take this long to respond, so a smaller timeout would miss nodes. int timeout = 30; // Attempt to connect to the process with the handshake without low priority. Stream nodeStream = NamedPipeUtil.TryConnectToProcess(nodeProcess.Id, timeout, NodeProviderOutOfProc.GetHandshake(nodeReuse, enableLowPriority: false, specialNode: false)); // If we couldn't connect attempt to connect to the process with the handshake including low priority. nodeStream ??= NamedPipeUtil.TryConnectToProcess(nodeProcess.Id, timeout, NodeProviderOutOfProc.GetHandshake(nodeReuse, enableLowPriority: true, specialNode: false)); // Attempt to connect to the non-worker process // Attempt to connect to the process with the handshake without low priority. nodeStream ??= NamedPipeUtil.TryConnectToProcess(nodeProcess.Id, timeout, NodeProviderOutOfProc.GetHandshake(nodeReuse, enableLowPriority: false, specialNode: true)); // If we couldn't connect attempt to connect to the process with the handshake including low priority. nodeStream ??= NamedPipeUtil.TryConnectToProcess(nodeProcess.Id, timeout, NodeProviderOutOfProc.GetHandshake(nodeReuse, enableLowPriority: true, specialNode: true)); if (nodeStream != null) { // If we're able to connect to such a process, send a packet requesting its termination CommunicationsUtilities.Trace("Shutting down node with pid = {0}", nodeProcess.Id); NodeContext nodeContext = new NodeContext(0, nodeProcess.Id, nodeStream, factory, terminateNode); nodeContext.SendData(new NodeBuildComplete(false /* no node reuse */)); nodeStream.Dispose(); } } }
/// <summary> /// Shuts down all of the managed nodes permanently. /// </summary> /// <param name="hostHandshake">host handshake key</param> /// <param name="clientHandshake">client handshake key</param> /// <param name="terminateNode">Delegate used to tell the node provider that a context has terminated</param> protected void ShutdownAllNodes(long hostHandshake, long clientHandshake, NodeContextTerminateDelegate terminateNode) { // INodePacketFactory INodePacketFactory factory = new NodePacketFactory(); // Find proper msbuild executable name string msbuildExeName = Environment.GetEnvironmentVariable("MSBUILD_EXE_NAME"); if (String.IsNullOrEmpty(msbuildExeName)) { msbuildExeName = "MSBuild.exe"; } // Search for all instances of the msbuild process and create a list of them List <Process> nodeProcesses = new List <Process>(Process.GetProcessesByName(Path.GetFileNameWithoutExtension(msbuildExeName))); // Find proper MSBuildTaskHost executable name string msbuildtaskhostExeName = NodeProviderOutOfProcTaskHost.TaskHostNameForClr2TaskHost; // Search for all instances of msbuildtaskhost process and add them to the process list nodeProcesses.AddRange(new List <Process>(Process.GetProcessesByName(Path.GetFileNameWithoutExtension(msbuildtaskhostExeName)))); // For all processes in the list, send signal to terminate if able to connect foreach (Process nodeProcess in nodeProcesses) { NamedPipeClientStream nodeStream = TryConnectToProcess(nodeProcess.Id, 30 /*verified to miss nodes if smaller*/, hostHandshake, clientHandshake); if (null != nodeStream) { // If we're able to connect to such a process, send a packet requesting its termination CommunicationsUtilities.Trace("Shutting down node with pid = {0}", nodeProcess.Id); NodeContext nodeContext = new NodeContext(0, nodeProcess.Id, nodeStream, factory, terminateNode); nodeContext.SendData(new NodeBuildComplete(false /* no node reuse */)); nodeStream.Close(); } } }
/// <summary> /// Constructor. /// </summary> public OutOfProcTaskHostNode() { // We don't know what the current build thinks this variable should be until RunTask(), but as a fallback in case there are // communications before we get the configuration set up, just go with what was already in the environment from when this node // was initially launched. _debugCommunications = (Environment.GetEnvironmentVariable("MSBUILDDEBUGCOMM") == "1"); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(ExceptionHandling.UnhandledExceptionHandler); _receivedPackets = new Queue<INodePacket>(); // These WaitHandles are disposed in HandleShutDown() _packetReceivedEvent = new AutoResetEvent(false); _shutdownEvent = new ManualResetEvent(false); _taskCompleteEvent = new AutoResetEvent(false); _taskCancelledEvent = new ManualResetEvent(false); _packetFactory = new NodePacketFactory(); INodePacketFactory thisINodePacketFactory = (INodePacketFactory)this; thisINodePacketFactory.RegisterPacketHandler(NodePacketType.TaskHostConfiguration, TaskHostConfiguration.FactoryForDeserialization, this); thisINodePacketFactory.RegisterPacketHandler(NodePacketType.TaskHostTaskCancelled, TaskHostTaskCancelled.FactoryForDeserialization, this); thisINodePacketFactory.RegisterPacketHandler(NodePacketType.NodeBuildComplete, NodeBuildComplete.FactoryForDeserialization, this); }
private NodeManager() { _nodeIdToProvider = new Dictionary <int, INodeProvider>(); _packetFactory = new NodePacketFactory(); _nextNodeId = _inprocNodeId + 1; }
/// <summary> /// Initializes the component. /// </summary> /// <param name="host">The component host.</param> public void InitializeComponent(IBuildComponentHost host) { this.ComponentHost = host; _nodeContexts = new Dictionary<TaskHostContext, NodeContext>(); _nodeIdToPacketFactory = new Dictionary<int, INodePacketFactory>(); _nodeIdToPacketHandler = new Dictionary<int, INodePacketHandler>(); _activeNodes = new HashSet<int>(); _noNodesActiveEvent = new ManualResetEvent(true); _localPacketFactory = new NodePacketFactory(); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.LogMessage, LogMessagePacket.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.TaskHostTaskComplete, TaskHostTaskComplete.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.NodeShutdown, NodeShutdown.FactoryForDeserialization, this); }
/// <summary> /// Shuts down all of the managed nodes permanently. /// </summary> /// <param name="hostHandshake">host handshake key</param> /// <param name="clientHandshake">client handshake key</param> /// <param name="terminateNode">Delegate used to tell the node provider that a context has terminated</param> protected void ShutdownAllNodes(long hostHandshake, long clientHandshake, NodeContextTerminateDelegate terminateNode) { // INodePacketFactory INodePacketFactory factory = new NodePacketFactory(); // Find proper msbuild executable name string msbuildExeName = Environment.GetEnvironmentVariable("MSBUILD_EXE_NAME"); if (String.IsNullOrEmpty(msbuildExeName)) { msbuildExeName = "MSBuild.exe"; } // Search for all instances of the msbuild process and create a list of them List<Process> nodeProcesses = new List<Process>(Process.GetProcessesByName(Path.GetFileNameWithoutExtension(msbuildExeName))); // Find proper MSBuildTaskHost executable name string msbuildtaskhostExeName = NodeProviderOutOfProcTaskHost.TaskHostNameForClr2TaskHost; // Search for all instances of msbuildtaskhost process and add them to the process list nodeProcesses.AddRange(new List<Process>(Process.GetProcessesByName(Path.GetFileNameWithoutExtension(msbuildtaskhostExeName)))); // For all processes in the list, send signal to terminate if able to connect foreach (Process nodeProcess in nodeProcesses) { NamedPipeClientStream nodeStream = TryConnectToProcess(nodeProcess.Id, 30/*verified to miss nodes if smaller*/, hostHandshake, clientHandshake); if (null != nodeStream) { // If we're able to connect to such a process, send a packet requesting its termination CommunicationsUtilities.Trace("Shutting down node with pid = {0}", nodeProcess.Id); NodeContext nodeContext = new NodeContext(0, nodeProcess.Id, nodeStream, factory, terminateNode); nodeContext.SendData(new NodeBuildComplete(false /* no node reuse */)); nodeStream.Close(); } } }
/// <summary> /// Constructor. /// </summary> private NodeManager() { _nodeIdToProvider = new Dictionary<int, INodeProvider>(); _packetFactory = new NodePacketFactory(); _nextNodeId = _inprocNodeId + 1; }
/// <summary> /// Reset the state of objects in the node manager which need to be reset between builds. /// </summary> public void ClearPerBuildState() { _packetFactory = new NodePacketFactory(); _nodeIdToProvider.Clear(); // because the inproc node is always 1 therefore when new nodes are requested we need to start at 2 _nextNodeId = _inprocNodeId + 1; }
/// <summary> /// Constructor /// </summary> public TaskHostTask(IElementLocation taskLocation, TaskLoggingContext taskLoggingContext, IBuildComponentHost buildComponentHost, IDictionary<string, string> taskHostParameters, LoadedType taskType, AppDomainSetup appDomainSetup) { ErrorUtilities.VerifyThrowInternalNull(taskType, "taskType"); _taskLocation = taskLocation; _taskLoggingContext = taskLoggingContext; _buildComponentHost = buildComponentHost; _taskType = taskType; _appDomainSetup = appDomainSetup; _taskHostParameters = taskHostParameters; _packetFactory = new NodePacketFactory(); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.LogMessage, LogMessagePacket.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.TaskHostTaskComplete, TaskHostTaskComplete.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.NodeShutdown, NodeShutdown.FactoryForDeserialization, this); _packetReceivedEvent = new AutoResetEvent(false); _receivedPackets = new Queue<INodePacket>(); _taskHostLock = new Object(); _setParameters = new Dictionary<string, object>(); }
/// <summary> /// Constructor. /// </summary> public OutOfProcNode() { s_isOutOfProcNode = true; AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(ExceptionHandling.UnhandledExceptionHandler); _debugCommunications = (Environment.GetEnvironmentVariable("MSBUILDDEBUGCOMM") == "1"); _receivedPackets = new Queue<INodePacket>(); _packetReceivedEvent = new AutoResetEvent(false); _shutdownEvent = new ManualResetEvent(false); _legacyThreadingData = new LegacyThreadingData(); _componentFactories = new BuildComponentFactoryCollection(this); _componentFactories.RegisterDefaultFactories(); _packetFactory = new NodePacketFactory(); _buildRequestEngine = (this as IBuildComponentHost).GetComponent(BuildComponentType.RequestEngine) as IBuildRequestEngine; _globalConfigCache = (this as IBuildComponentHost).GetComponent(BuildComponentType.ConfigCache) as IConfigCache; _taskHostNodeManager = (this as IBuildComponentHost).GetComponent(BuildComponentType.TaskHostNodeManager) as INodeManager; if (s_projectRootElementCache == null) { s_projectRootElementCache = new ProjectRootElementCache(true /* automatically reload any changes from disk */); } _buildRequestEngine.OnEngineException += new EngineExceptionDelegate(OnEngineException); _buildRequestEngine.OnNewConfigurationRequest += new NewConfigurationRequestDelegate(OnNewConfigurationRequest); _buildRequestEngine.OnRequestBlocked += new RequestBlockedDelegate(OnNewRequest); _buildRequestEngine.OnRequestComplete += new RequestCompleteDelegate(OnRequestComplete); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.BuildRequest, BuildRequest.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.BuildRequestConfiguration, BuildRequestConfiguration.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.BuildRequestConfigurationResponse, BuildRequestConfigurationResponse.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.BuildRequestUnblocker, BuildRequestUnblocker.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.NodeConfiguration, NodeConfiguration.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.NodeBuildComplete, NodeBuildComplete.FactoryForDeserialization, this); }