Beispiel #1
0
        /// <summary>
        /// Indicates that there are results which can be used to unblock this request.  Updates the relationships between requests.
        /// </summary>
        public void UnblockWithResult(BuildResult result)
        {
            VerifyOneOfStates(new SchedulableRequestState[] { SchedulableRequestState.Blocked, SchedulableRequestState.Unscheduled });
            ErrorUtilities.VerifyThrowArgumentNull(result, "result");

            BlockingRequestKey key = new BlockingRequestKey(result);

            DisconnectRequestWeAreBlockedBy(key);
            _activeTargetsWhenBlocked = null;
            BlockingTarget            = null;
        }
Beispiel #2
0
            /// <summary>
            /// Equals override.
            /// </summary>
            public override bool Equals(object obj)
            {
                if (obj != null)
                {
                    BlockingRequestKey other = obj as BlockingRequestKey;
                    if (other != null)
                    {
                        return((other._globalRequestId == _globalRequestId) && (other._nodeRequestId == _nodeRequestId));
                    }
                }

                return(base.Equals(obj));
            }
Beispiel #3
0
        /// <summary>
        /// Removes the association between this request and the one we are blocked by.
        /// </summary>
        internal void DisconnectRequestWeAreBlockedBy(BlockingRequestKey blockingRequestKey)
        {
            ErrorUtilities.VerifyThrow(_requestsWeAreBlockedBy.TryGetValue(blockingRequestKey, out SchedulableRequest unblockingRequest), "We are not blocked by the specified request.");
            ErrorUtilities.VerifyThrow(unblockingRequest._requestsWeAreBlocking.Contains(this), "The request unblocking us doesn't think it is blocking us.");

            _requestsWeAreBlockedBy.Remove(blockingRequestKey);
            unblockingRequest._requestsWeAreBlocking.Remove(this);

            // If the request we are blocked by also happens to be unscheduled, remove it as well so we don't try to run it later.  This is
            // because circular dependency errors cause us to fail all outstanding requests on the current request.  See BuildRequsetEntry.ReportResult.
            if (unblockingRequest.State == SchedulableRequestState.Unscheduled)
            {
                unblockingRequest.Delete();
            }

            if (_requestsWeAreBlockedBy.Count == 0)
            {
                ChangeToState(SchedulableRequestState.Ready);
            }
        }
        /// <summary>
        /// Removes the association between this request and the one we are blocked by.
        /// </summary>
        private void DisconnectRequestWeAreBlockedBy(BlockingRequestKey blockingRequestKey)
        {
            ErrorUtilities.VerifyThrow(_requestsWeAreBlockedBy.ContainsKey(blockingRequestKey), "We are not blocked by the specified request.");

            SchedulableRequest unblockingRequest = _requestsWeAreBlockedBy[blockingRequestKey];
            ErrorUtilities.VerifyThrow(unblockingRequest._requestsWeAreBlocking.Contains(this), "The request unblocking us doesn't think it is blocking us.");

            _requestsWeAreBlockedBy.Remove(blockingRequestKey);
            unblockingRequest._requestsWeAreBlocking.Remove(this);

            // If the request we are blocked by also happens to be unscheduled, remove it as well so we don't try to run it later.  This is 
            // because circular dependency errors cause us to fail all outstanding requests on the current request.  See BuildRequsetEntry.ReportResult.
            if (unblockingRequest.State == SchedulableRequestState.Unscheduled)
            {
                unblockingRequest.Delete();
            }

            if (_requestsWeAreBlockedBy.Count == 0)
            {
                ChangeToState(SchedulableRequestState.Ready);
            }
        }
        /// <summary>
        /// Removes associations with all blocking requests and throws an exception.
        /// </summary>
        private void CleanupForCircularDependencyAndThrow(SchedulableRequest requestCausingFailure, List<SchedulableRequest> ancestors)
        {
            if (_requestsWeAreBlockedBy.Count != 0)
            {
                List<SchedulableRequest> tempRequests = new List<SchedulableRequest>(_requestsWeAreBlockedBy.Values);
                foreach (SchedulableRequest requestWeAreBlockedBy in tempRequests)
                {
                    BlockingRequestKey key = new BlockingRequestKey(requestWeAreBlockedBy.BuildRequest);
                    DisconnectRequestWeAreBlockedBy(key);
                }
            }
            else
            {
                ChangeToState(SchedulableRequestState.Ready);
            }

            _activeTargetsWhenBlocked = null;

            // The blocking request itself is no longer valid if it was unscheduled.
            if (requestCausingFailure.State == SchedulableRequestState.Unscheduled)
            {
                requestCausingFailure.Delete();
            }

            throw new SchedulerCircularDependencyException(requestCausingFailure.BuildRequest, ancestors);
        }
        /// <summary>
        /// Indicates that there are results which can be used to unblock this request.  Updates the relationships between requests.
        /// </summary>
        public void UnblockWithResult(BuildResult result)
        {
            VerifyOneOfStates(new SchedulableRequestState[] { SchedulableRequestState.Blocked, SchedulableRequestState.Unscheduled });
            ErrorUtilities.VerifyThrowArgumentNull(result, "result");

            BlockingRequestKey key = new BlockingRequestKey(result);
            DisconnectRequestWeAreBlockedBy(key);
            _activeTargetsWhenBlocked = null;
        }
        /// <summary>
        /// Marks this request as being blocked by the specified request.  Establishes the correct relationships between the requests.
        /// </summary>
        /// <param name="blockingRequest">The request which is blocking this one.</param>
        /// <param name="activeTargets">The list of targets this request was currently building at the time it became blocked.</param>
        public void BlockByRequest(SchedulableRequest blockingRequest, string[] activeTargets)
        {
            VerifyOneOfStates(new SchedulableRequestState[] { SchedulableRequestState.Blocked, SchedulableRequestState.Executing });
            ErrorUtilities.VerifyThrowArgumentNull(blockingRequest, "blockingRequest");
            ErrorUtilities.VerifyThrowArgumentNull(activeTargets, "activeTargets");

            // Note that the blocking request will typically be our parent UNLESS it is a request we blocked on because it was executing a target we wanted to execute.
            // Thus, we do not assert the parent-child relationship here.
            BlockingRequestKey key = new BlockingRequestKey(blockingRequest.BuildRequest);
            ErrorUtilities.VerifyThrow(!_requestsWeAreBlockedBy.ContainsKey(key), "We are already blocked by this request.");
            ErrorUtilities.VerifyThrow(!blockingRequest._requestsWeAreBlocking.Contains(this), "The blocking request thinks it is already blocking us.");

            // This method is only called when a request reports that it is blocked on other requests.  If the request is being blocked by a brand new
            // request, that request will be unscheduled.  If this request is blocked by an in-progress request which was executing a target it needed
            // to also execute, then that request is not unscheduled (because it was running on the node) and it is not executing (because this condition
            // can only occur against requests which are executing on the same node and since the request which called this method is the one currently
            // executing on that node, that means the request it is blocked by must either be itself blocked or ready.)
            blockingRequest.VerifyOneOfStates(new SchedulableRequestState[] { SchedulableRequestState.Yielding, SchedulableRequestState.Blocked, SchedulableRequestState.Ready, SchedulableRequestState.Unscheduled });

            // Update our list of active targets.  This has to be done before we detect circular dependencies because we use this information to detect
            // re-entrancy circular dependencies.
            _activeTargetsWhenBlocked = activeTargets;
            DetectCircularDependency(blockingRequest);

            _requestsWeAreBlockedBy[key] = blockingRequest;
            blockingRequest._requestsWeAreBlocking.Add(this);

            ChangeToState(SchedulableRequestState.Blocked);
        }