Example #1
0
        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
        }
Example #3
0
        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;
        }
Example #4
0
        /// <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);
        }
Example #8
0
 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);
        }
Example #10
0
        /// <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();
                }
            }
        }
Example #11
0
 /// <summary>
 /// Constructor.
 /// </summary>
 private NodeManager()
 {
     _nodeIdToProvider = new Dictionary<int, INodeProvider>();
     _packetFactory = new NodePacketFactory();
     _nextNodeId = _inprocNodeId + 1;
 }
Example #12
0
        /// <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;
        }
Example #13
0
        /// <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>();
        }
Example #14
0
        /// <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);
        }