Beispiel #1
0
        /// <summary>
        /// This method creates a BuildResult using the information contained in a completed build request and
        /// then routes it to the right node. On a child process, this means either consume the result localy,
        /// or send it to the parent node. On a parent node, this means either consume the result locally or
        /// send it to a child node
        /// </summary>
        internal void PostDoneNotice(BuildRequest buildRequest)
        {
            // Create a container with the results of the evaluation
            BuildResult buildResult = buildRequest.GetBuildResult();

            // If we're supposed to use caching and this request wasn't restored from cache, cache it
            if (buildRequest.UseResultsCache && !buildRequest.RestoredFromCache)
            {
                CacheScope cacheScope = parentEngine.CacheManager.GetCacheScope(buildRequest.ProjectFileName, buildRequest.GlobalProperties, buildRequest.ToolsetVersion, CacheContentType.BuildResults);
                cacheScope.AddCacheEntryForBuildResults(buildResult);
            }

            // an external request is any request that came from the parent engine, all requests to a child are external
            // unless the project was alredy loaded on the node itself
            if (buildRequest.IsExternalRequest)
            {
                // If the build request was send from outside the current process,
                // send the results to the parent engine
                parentNode.PostBuildResultToHost(buildResult);
            }
            else
            {
                // In the case of a child process, getting to this point means the request will be satisfied locally, the node index should be 0
                // on the parent engine however, the node index can be, 0 for the local node, or can be >0 which represents a child node
                PostDoneNotice(buildRequest.NodeIndex, buildResult);
            }
        }
Beispiel #2
0
        /// <summary>
        /// This method is called once the engine has decided to sent a build request to a child node.
        /// Route the given BuildRequest to the given node. If necessary a routing context is
        /// created to manage future communication with the node regarding the build request.
        /// </summary>
        internal void PostBuildRequest(BuildRequest currentRequest, int nodeIndex)
        {
            // if the request is to be sent to the parent node, post the request back to the host
            if (nodeIndex == EngineCallback.parentNode)
            {
                ParentNode.PostBuildRequestToHost(currentRequest);
            }
            else
            {
                // Dont create any contexts if the request was supposed to be processed on the current node
                if (nodeIndex != EngineCallback.inProcNode)
                {
                    // Get the cache scope for the request (possibly creating it). The cache scope will contain the taskoutputs of the build request
                    // which can be reused of the same project/toolsversion/globalproperties is asked for again.
                    CacheScope cacheScope = parentEngine.CacheManager.GetCacheScope(currentRequest.ProjectFileName, currentRequest.GlobalProperties, currentRequest.ToolsetVersion, CacheContentType.BuildResults);

                    // Create a routing context and update the request to refer to the new node handle id
                    int parentHandleId = currentRequest.HandleId;
                    currentRequest.HandleId =
                        parentEngine.EngineCallback.CreateRoutingContext
                            (nodeIndex, currentRequest.HandleId, currentRequest.NodeIndex,
                            currentRequest.RequestId, cacheScope, currentRequest, null);

                    if (scheduler != null)
                    {
                        // Check to see if we need to change the traversal strategy of the system
                        // parentHandleId and node index are not used in the function so it can be ignored
                        scheduler.NotifyOfBuildRequest(nodeIndex, currentRequest, parentHandleId);
                    }

                    nodeManager.PostBuildRequestToNode(nodeIndex, currentRequest);
                }
            }
        }
Beispiel #3
0
        private CacheScope GetCacheScopeIfExists(string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType)
        {
            CacheScope cacheScope = null;

            // Default the version to the default engine version
            if (scopeToolsVersion == null)
            {
                scopeToolsVersion = defaultToolsVersion;
            }

            // Retrieve list of scopes by this name
            if (cacheContents[(int)cacheContentType].ContainsKey(scopeName))
            {
                List <CacheScope> scopesByName = (List <CacheScope>)cacheContents[(int)cacheContentType][scopeName];

                // If the list exists search for matching scope properties otherwise create the list
                if (scopesByName != null)
                {
                    lock (cacheManagerLock)
                    {
                        for (int i = 0; i < scopesByName.Count; i++)
                        {
                            if (scopesByName[i].ScopeProperties.IsEquivalent(scopeProperties) && (String.Compare(scopeToolsVersion, scopesByName[i].ScopeToolsVersion, StringComparison.OrdinalIgnoreCase) == 0))
                            {
                                cacheScope = scopesByName[i];
                                break;
                            }
                        }
                    }
                }
            }

            return(cacheScope);
        }
Beispiel #4
0
        /// <summary>
        /// This method return a cache scope with particular name and properties. If the cache
        /// scope doesn't exist it will be created. This method is thread safe.
        /// </summary>
        internal CacheScope GetCacheScope(string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType)
        {
            // If the version is not specified default to the engine version
            if (scopeToolsVersion == null)
            {
                scopeToolsVersion = defaultToolsVersion;
            }

            // Retrieve the cache scope if it exists
            CacheScope cacheScope = GetCacheScopeIfExists(scopeName, scopeProperties, scopeToolsVersion, cacheContentType);

            // If the scope doesn't exist create it
            if (cacheScope == null)
            {
                lock (cacheManagerLock)
                {
                    cacheScope = GetCacheScopeIfExists(scopeName, scopeProperties, scopeToolsVersion, cacheContentType);

                    if (cacheScope == null)
                    {
                        // If the list of scopes doesn't exist create it
                        if (!cacheContents[(int)cacheContentType].ContainsKey(scopeName))
                        {
                            cacheContents[(int)cacheContentType].Add(scopeName, new List <CacheScope>());
                        }
                        // Create the scope and add it to the list
                        List <CacheScope> scopesByName = (List <CacheScope>)cacheContents[(int)cacheContentType][scopeName];
                        cacheScope = new CacheScope(scopeName, scopeProperties, scopeToolsVersion);
                        scopesByName.Add(cacheScope);
                    }
                }
            }

            return(cacheScope);
        }
Beispiel #5
0
 internal NodeRequestMapping
     (int handleId, int requestId, CacheScope resultsCache)
 {
     ErrorUtilities.VerifyThrow(resultsCache != null, "Expect a non-null build result");
     this.handleId     = handleId;
     this.requestId    = requestId;
     this.resultsCache = resultsCache;
 }
Beispiel #6
0
        /// <summary>
        /// Sets multiple cache entries for the given scope
        /// </summary>
        /// <param name="entries"></param>
        /// <param name="scopeName"></param>
        /// <param name="scopeProperties"></param>
        internal void SetCacheEntries(CacheEntry[] entries, string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType)
        {
            // If the list exists search for matching scope properties otherwise create the list
            CacheScope cacheScope = GetCacheScope(scopeName, scopeProperties, scopeToolsVersion, cacheContentType);

            // Add the entry to the right scope
            cacheScope.AddCacheEntries(entries);
        }
Beispiel #7
0
        /// <summary>
        /// Gets multiple cache entries from the given scope.
        /// </summary>
        /// <param name="names"></param>
        /// <param name="scopeName"></param>
        /// <param name="scopeProperties"></param>
        /// <returns></returns>
        internal CacheEntry[] GetCacheEntries(string[] names, string scopeName, BuildPropertyGroup scopeProperties, string scopeToolsVersion, CacheContentType cacheContentType)
        {
            CacheScope cacheScope = GetCacheScopeIfExists(scopeName, scopeProperties, scopeToolsVersion, cacheContentType);

            if (cacheScope != null)
            {
                return(cacheScope.GetCacheEntries(names));
            }

            return(new CacheEntry[names.Length]);
        }
Beispiel #8
0
Datei: Node.cs Projekt: 3F/IeXod
        internal void PostBuildRequestToHost(BuildRequest currentRequest)
        {
            // Since this request is going back to the host the local node should not have a project object for it
            ErrorUtilities.VerifyThrow(currentRequest.ProjectToBuild == null, "Should not have a project object");
            // Add the request to the mapping hashtable so that we can recognize the outputs
            CacheScope         cacheScope         = localEngine.CacheManager.GetCacheScope(currentRequest.ProjectFileName, currentRequest.GlobalProperties, currentRequest.ToolsetVersion, CacheContentType.BuildResults);
            NodeRequestMapping nodeRequestMapping =
                new NodeRequestMapping(currentRequest.HandleId, currentRequest.RequestId, cacheScope);

            lock (requestToLocalIdMapping)
            {
                requestToLocalIdMapping.Add(lastRequestIdUsed, nodeRequestMapping);
                // Keep the request id local for this node
                currentRequest.RequestId = lastRequestIdUsed;
                lastRequestIdUsed++;
            }

            // Find the original external request that caused us to run this task
            TaskExecutionContext taskExecutionContext = localEngine.EngineCallback.GetTaskContextFromHandleId(currentRequest.HandleId);

            while (!taskExecutionContext.BuildContext.BuildRequest.IsExternalRequest)
            {
                ErrorUtilities.VerifyThrow(taskExecutionContext.BuildContext.BuildRequest.IsGeneratedRequest,
                                           "Must be a generated request");

                taskExecutionContext =
                    localEngine.EngineCallback.GetTaskContextFromHandleId(taskExecutionContext.BuildContext.BuildRequest.HandleId);
            }

            //Modify the request with the data that is expected by the parent engine
            currentRequest.HandleId  = taskExecutionContext.BuildContext.BuildRequest.HandleId;
            currentRequest.NodeIndex = taskExecutionContext.BuildContext.BuildRequest.NodeIndex;

            try
            {
                outProcLoggingService.ProcessPostedLoggingEvents();
                parentCallback.PostBuildRequestsToHost(new BuildRequest[] { currentRequest });
            }
            catch (Exception e)
            {
                ReportUnhandledError(e);
            }
        }
Beispiel #9
0
 /// <summary>
 /// Default constructor for a routing context
 /// </summary>
 internal RequestRoutingContext
 (
     int handleId,
     int nodeIndex,
     int parentHandleId,
     int parentNodeIndex,
     int parentRequestId,
     CacheScope cacheScope,
     BuildRequest triggeringBuildRequest,
     BuildEventContext buildEventContext
 )
     : base(handleId, nodeIndex, buildEventContext)
 {
     this.parentHandleId         = parentHandleId;
     this.parentNodeIndex        = parentNodeIndex;
     this.parentRequestId        = parentRequestId;
     this.cacheScope             = cacheScope;
     this.triggeringBuildRequest = triggeringBuildRequest;
 }
Beispiel #10
0
        /// <summary>
        /// This method creates a new routing context. This method is not thread safe and must be called
        /// only from the engine thread.
        /// </summary>
        internal int CreateRoutingContext
        (
            int nodeIndex,
            int parentHandleId,
            int parentNodeIndex,
            int parentRequestId,
            CacheScope cacheScope,
            BuildRequest triggeringBuildRequest,
            BuildEventContext buildEventContext
        )
        {
            int handleId = nextContextId;

            nextContextId = nextContextId + 1;

            RequestRoutingContext executionContext =
                new RequestRoutingContext(handleId, nodeIndex, parentHandleId, parentNodeIndex, parentRequestId,
                                          cacheScope, triggeringBuildRequest, buildEventContext);

            executionContexts.Add(handleId, executionContext);

            return(handleId);
        }
Beispiel #11
0
        /// <summary>
        /// This method get a result from the cache if every target is cached.
        /// If any of the target are not present in the cache null is returned. This method is not thread safe.
        /// </summary>
        internal BuildResult GetCachedBuildResult(BuildRequest buildRequest, out ArrayList actuallyBuiltTargets)
        {
            actuallyBuiltTargets = null;

            if (!buildRequest.UseResultsCache)
            {
                return(null);
            }

            // Retrieve list of scopes by this name
            string projectName = buildRequest.ProjectToBuild == null ?
                                 buildRequest.ProjectFileName : buildRequest.ProjectToBuild.FullFileName;

            // If the list exists search for matching scope properties otherwise create the list
            CacheScope cacheScope = GetCacheScopeIfExists(projectName, buildRequest.GlobalProperties, buildRequest.ToolsetVersion, CacheContentType.BuildResults);

            // If there is no cache entry for this project return null
            if (cacheScope == null)
            {
                return(null);
            }

            return(cacheScope.GetCachedBuildResult(buildRequest, out actuallyBuiltTargets));
        }