/// <summary> /// Constructs <seealso cref="NamedPipeClientStream"/> /// </summary> NamedPipeClientStream IRarBuildEngine.GetRarClientStream(string pipeName, int timeout) { BuildParameters parameters = _host.BuildParameters; Handshake handshake = NodeProviderOutOfProc.GetHandshake(enableNodeReuse: parameters.EnableNodeReuse, enableLowPriority: parameters.LowPriority, specialNode: true); return(NamedPipeUtil.TryConnectToProcess(pipeName, timeout, handshake)); }
/// <summary> /// Shuts down all of the managed nodes permanently. /// </summary> public void ShutdownAllNodes() { // if no BuildParameters were specified for this build, // we must be trying to shut down idle nodes from some // other, completed build. If they're still around, // they must have been started with node reuse. bool nodeReuse = ComponentHost.BuildParameters?.EnableNodeReuse ?? true; ShutdownAllNodes(NodeProviderOutOfProc.GetHostHandshake(nodeReuse), NodeProviderOutOfProc.GetClientHandshake(), NodeContextTerminated); }
/// <summary> /// Shuts down all of the managed nodes permanently. /// </summary> public void ShutdownAllNodes() { bool nodeReuse = ComponentHost.BuildParameters.EnableNodeReuse; // To avoid issues with mismatched priorities not shutting // down all the nodes on exit, we will attempt to shutdown // all matching notes with and without the priroity bit set. // So precompute both versions of the handshake now. long hostHandshake = NodeProviderOutOfProc.GetHostHandshake(nodeReuse, enableLowPriority: false); long hostHandshakeWithLow = NodeProviderOutOfProc.GetHostHandshake(nodeReuse, enableLowPriority: true); ShutdownAllNodes(nodeReuse, NodeContextTerminated); }
/// <summary> /// Shuts down all of the managed nodes permanently. /// </summary> public void ShutdownAllNodes() { // If no BuildParameters were specified for this build, // we must be trying to shut down idle nodes from some // other, completed build. If they're still around, // they must have been started with node reuse. bool nodeReuse = ComponentHost.BuildParameters?.EnableNodeReuse ?? true; // To avoid issues with mismatched priorities not shutting // down all the nodes on exit, we will attempt to shutdown // all matching nodes with and without the priority bit set. // This means we need both versions of the handshake. ShutdownAllNodes( NodeProviderOutOfProc.GetHostHandshake(nodeReuse, enableLowPriority: false), NodeProviderOutOfProc.GetHostHandshake(nodeReuse, enableLowPriority: true), NodeProviderOutOfProc.GetClientHandshake(), NodeContextTerminated); }
/// <summary> /// Instantiates a new MSBuild process acting as a child node. /// </summary> public bool CreateNode(int nodeId, INodePacketFactory factory, NodeConfiguration configuration) { ErrorUtilities.VerifyThrowArgumentNull(factory, "factory"); if (_nodeContexts.Count == ComponentHost.BuildParameters.MaxNodeCount) { ErrorUtilities.ThrowInternalError("All allowable nodes already created ({0}).", _nodeContexts.Count); return(false); } // Start the new process. We pass in a node mode with a node number of 1, to indicate that we // want to start up just a standard MSBuild out-of-proc node. string commandLineArgs = " /nologo /nodemode:1 "; // Disable node re-use if it is not requested (because no argument means enable reuse). if (!ComponentHost.BuildParameters.EnableNodeReuse) { commandLineArgs += "/nodeReuse:false"; } // Make it here. CommunicationsUtilities.Trace("Starting to acquire a new or existing node to establish node ID {0}...", nodeId); NodeContext context = GetNode(null, commandLineArgs, nodeId, factory, NodeProviderOutOfProc.GetHostHandshake(ComponentHost.BuildParameters.EnableNodeReuse), NodeProviderOutOfProc.GetClientHandshake(), NodeContextTerminated); if (null != context) { _nodeContexts[nodeId] = context; // Start the asynchronous read. context.BeginAsyncPacketRead(); // Configure the node. context.SendData(configuration); return(true); } throw new BuildAbortedException(ResourceUtilities.FormatResourceString("CouldNotConnectToMSBuildExe", ComponentHost.BuildParameters.NodeExeLocation)); }
/// <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 = TryConnectToProcess(nodeProcess.Id, timeout, NodeProviderOutOfProc.GetHandshake(nodeReuse, false)); if (nodeStream == null) { // If we couldn't connect attempt to connect to the process with the handshake including low priority. nodeStream = TryConnectToProcess(nodeProcess.Id, timeout, NodeProviderOutOfProc.GetHandshake(nodeReuse, 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, nodeStream, factory, terminateNode); nodeContext.SendData(new NodeBuildComplete(false /* no node reuse */)); nodeStream.Dispose(); } } }
/// <summary> /// Instantiates a new MSBuild process acting as a child node. /// </summary> public bool CreateNode(int nodeId, INodePacketFactory factory, NodeConfiguration configuration) { ErrorUtilities.VerifyThrowArgumentNull(factory, "factory"); if (_nodeContexts.Count == ComponentHost.BuildParameters.MaxNodeCount) { ErrorUtilities.ThrowInternalError("All allowable nodes already created ({0}).", _nodeContexts.Count); return(false); } // Start the new process. We pass in a node mode with a node number of 1, to indicate that we // want to start up just a standard MSBuild out-of-proc node. // Note: We need to always pass /nodeReuse to ensure the value for /nodeReuse from msbuild.rsp // (next to msbuild.exe) is ignored. string commandLineArgs = $"/nologo /nodemode:1 /nodeReuse:{ComponentHost.BuildParameters.EnableNodeReuse.ToString().ToLower()} /low:{ComponentHost.BuildParameters.LowPriority.ToString().ToLower()}"; // Make it here. CommunicationsUtilities.Trace("Starting to acquire a new or existing node to establish node ID {0}...", nodeId); long hostHandShake = NodeProviderOutOfProc.GetHostHandshake(ComponentHost.BuildParameters.EnableNodeReuse, ComponentHost.BuildParameters.LowPriority); NodeContext context = GetNode(null, commandLineArgs, nodeId, factory, hostHandShake, NodeProviderOutOfProc.GetClientHandshake(ComponentHost.BuildParameters.EnableNodeReuse, ComponentHost.BuildParameters.LowPriority), NodeContextTerminated); if (null != context) { _nodeContexts[nodeId] = context; // Start the asynchronous read. context.BeginAsyncPacketRead(); // Configure the node. context.SendData(configuration); return(true); } throw new BuildAbortedException(ResourceUtilities.FormatResourceStringStripCodeAndKeyword("CouldNotConnectToMSBuildExe", ComponentHost.BuildParameters.NodeExeLocation)); }
/// <summary> /// Shuts down all of the managed nodes permanently. /// </summary> public void ShutdownAllNodes() { ShutdownAllNodes(NodeProviderOutOfProc.GetHostHandshake(ComponentHost.BuildParameters.EnableNodeReuse), NodeProviderOutOfProc.GetClientHandshake(), NodeContextTerminated); }
/// <summary> /// Returns the client handshake for this node endpoint /// </summary> protected override long GetClientHandshake() { return(NodeProviderOutOfProc.GetClientHandshake(_enableReuse, _lowPriority)); }
/// <summary> /// Returns the client handshake for this node endpoint /// </summary> protected override long GetClientHandshake() { return(NodeProviderOutOfProc.GetClientHandshake()); }
/// <summary> /// Returns the host handshake for this node endpoint /// </summary> protected override long GetHostHandshake() { return(NodeProviderOutOfProc.GetHostHandshake(_enableReuse)); }