示例#1
0
 /// <summary>
 /// Constructs a response where a result should be sent or execution should be resumed.
 /// </summary>
 /// <param name="node">The node ID to which the result should be sent.</param>
 /// <param name="unblocker">The result to send.</param>
 private ScheduleResponse(int node, BuildRequestUnblocker unblocker)
 {
     Action      = (unblocker.Result == null) ? ScheduleActionType.ResumeExecution : ScheduleActionType.ReportResults;
     NodeId      = node;
     Unblocker   = unblocker;
     BuildResult = unblocker.Result;
 }
示例#2
0
 /// <summary>
 /// Constructs a response indicating there is a circular dependency caused by the specified request.
 /// </summary>
 private ScheduleResponse(int nodeId, BuildRequest parentRequest, BuildRequest requestCausingCircularDependency)
 {
     Action       = ScheduleActionType.CircularDependency;
     BuildRequest = requestCausingCircularDependency;
     NodeId       = nodeId;
     Unblocker    = new BuildRequestUnblocker(parentRequest, new BuildResult(requestCausingCircularDependency, true /* circularDependency */));
 }
示例#3
0
 /// <summary>
 /// Constructs a response where a result should be sent or execution should be resumed.
 /// </summary>
 /// <param name="node">The node ID to which the result should be sent.</param>
 /// <param name="unblocker">The result to send.</param>
 private ScheduleResponse(int node, BuildRequestUnblocker unblocker)
 {
     Action = (unblocker.Result == null) ? ScheduleActionType.ResumeExecution : ScheduleActionType.ReportResults;
     NodeId = node;
     Unblocker = unblocker;
     BuildResult = unblocker.Result;
 }
示例#4
0
 /// <summary>
 /// Constructs a response indicating there is a circular dependency caused by the specified request.
 /// </summary>
 private ScheduleResponse(int nodeId, BuildRequest parentRequest, BuildRequest requestCausingCircularDependency)
 {
     Action = ScheduleActionType.CircularDependency;
     BuildRequest = requestCausingCircularDependency;
     NodeId = nodeId;
     Unblocker = new BuildRequestUnblocker(parentRequest, new BuildResult(requestCausingCircularDependency, true /* circularDependency */));
 }
示例#5
0
 /// <summary>
 /// Handles the BuildResult packet.
 /// </summary>
 private void HandleBuildResult(BuildRequestUnblocker unblocker)
 {
     _buildRequestEngine.UnblockBuildRequest(unblocker);
 }
示例#6
0
 /// <summary>
 /// Handles the BuildResult packet.
 /// </summary>
 private void HandleBuildResult(BuildRequestUnblocker unblocker)
 {
     _buildRequestEngine.UnblockBuildRequest(unblocker);
 }
示例#7
0
        /// <summary>
        /// Reports a build result to the engine, allowing it to satisfy outstanding requests.  This result
        /// is reported to each entry, allowing it the opportunity to determine for itself if the
        /// result applies.
        /// </summary>
        /// <param name="unblocker">Information needed to unblock the engine.</param>
        /// <remarks>
        /// Called by the Node.  Non-overlapping with other calls from the Node.
        /// </remarks>
        public void UnblockBuildRequest(BuildRequestUnblocker unblocker)
        {
            QueueAction(
                () =>
                {
                    ErrorUtilities.VerifyThrow(_status != BuildRequestEngineStatus.Shutdown && _status != BuildRequestEngineStatus.Uninitialized, "Engine loop not yet started, status is {0}.", _status);
                    ErrorUtilities.VerifyThrow(_requestsByGlobalRequestId.ContainsKey(unblocker.BlockedRequestId), "Request {0} is not known to the engine.", unblocker.BlockedRequestId);
                    BuildRequestEntry entry = _requestsByGlobalRequestId[unblocker.BlockedRequestId];

                    // Are we resuming execution or reporting results?  
                    if (unblocker.Result == null)
                    {
                        // We are resuming execution.
                        TraceEngine("Request {0}({1}) (nr {2}) is now proceeding from current state {3}.", entry.Request.GlobalRequestId, entry.Request.ConfigurationId, entry.Request.NodeRequestId, entry.State);

                        // UNDONE: (Refactor) This is a bit icky because we still have the concept of blocking on an in-progress request
                        // versus blocking on requests waiting for results.  They come to the same thing, and its been rationalized correctly in
                        // the scheduler, but we should remove the dichotomy in the BuildRequestEntry so that that entry directly tracks in the same
                        // way as the SchedulableRequest does.  Alternately, it could just not track at all, and assume that when the scheduler tells it
                        // to resume it is able to do so (it has no other way of knowing anyhow.)
                        if (entry.State == BuildRequestEntryState.Waiting)
                        {
                            entry.Unblock();
                        }

                        ActivateBuildRequest(entry);
                    }
                    else
                    {
                        // We must be reporting results.                 
                        BuildResult result = unblocker.Result;

                        if (result.NodeRequestId == BuildRequest.ResultsTransferNodeRequestId)
                        {
                            TraceEngine("Request {0}({1}) (nr {2}) has retrieved the results for configuration {3} and cached them on node {4} (UBR).", entry.Request.GlobalRequestId, entry.Request.ConfigurationId, entry.Request.NodeRequestId, entry.Request.ConfigurationId, _componentHost.BuildParameters.NodeId);

                            IResultsCache resultsCache = (IResultsCache)_componentHost.GetComponent(BuildComponentType.ResultsCache);
                            IConfigCache configCache = (IConfigCache)_componentHost.GetComponent(BuildComponentType.ConfigCache);
                            BuildRequestConfiguration config = configCache[result.ConfigurationId];

                            config.RetrieveFromCache();
                            config.SavedEnvironmentVariables = ((IBuildResults)result).SavedEnvironmentVariables;
                            config.SavedCurrentDirectory = ((IBuildResults)result).SavedCurrentDirectory;
                            config.ApplyTransferredState(result.ProjectStateAfterBuild);

                            // Don't need them anymore on the result since they were just piggybacking to get accross the wire.
                            ((IBuildResults)result).SavedEnvironmentVariables = null;
                            ((IBuildResults)result).SavedCurrentDirectory = null;

                            // Our results node is now this node, since we've just cached those results                        
                            resultsCache.AddResult(result);
                            config.ResultsNodeId = _componentHost.BuildParameters.NodeId;

                            entry.Unblock();
                            ActivateBuildRequest(entry);
                        }
                        else
                        {
                            TraceEngine("Request {0}({1}) (nr {2}) is no longer waiting on nr {3} (UBR).  Results are {4}.", entry.Request.GlobalRequestId, entry.Request.ConfigurationId, entry.Request.NodeRequestId, result.NodeRequestId, result.OverallResult);

                            // Update the configuration with targets information, if we received any and didn't already have it.
                            if (result.DefaultTargets != null)
                            {
                                BuildRequestConfiguration configuration = _configCache[result.ConfigurationId];
                                if (configuration.ProjectDefaultTargets == null)
                                {
                                    configuration.ProjectDefaultTargets = result.DefaultTargets;
                                    configuration.ProjectInitialTargets = result.InitialTargets;
                                }
                            }

                            entry.ReportResult(result);
                        }
                    }
                },
                isLastTask: false);
        }