Пример #1
0
        private GraphReuseResult ReloadPipGraphOnly(
            EngineSerializer serializer,
            LoggingContext loggingContext,
            EngineState engineState,
            InputTracker.InputChanges inputChanges)
        {
            Tuple <PipGraph, EngineContext> t = null;

            try
            {
                t = EngineSchedule.LoadPipGraphAsync(
                    Context,
                    serializer,
                    Configuration,
                    loggingContext,
                    engineState).GetAwaiter().GetResult();
            }
            catch (BuildXLException e)
            {
                Logger.Log.FailedReloadPipGraph(loggingContext, e.ToString());
            }

            if (t == null)
            {
                return(GraphReuseResult.CreateForNoReuse(inputChanges));
            }

            var newContext = t.Item2;

            if (!ShouldReuseReloadedEngineContextGivenHistoricData(loggingContext, newContext.NextHistoricTableSizes))
            {
                return(GraphReuseResult.CreateForNoReuse(inputChanges));
            }

            var newPathTable = newContext.PathTable;
            var pathRemapper = new PathRemapper(Context.PathTable, newPathTable);

            Configuration = new ConfigurationImpl(Configuration, pathRemapper);

            m_initialCommandLineConfiguration = new CommandLineConfiguration(m_initialCommandLineConfiguration, pathRemapper);

            // Invalidate the old context to ensure nothing uses it anymore
            // Update engine state to deserialized state
            Context.Invalidate();
            Context = newContext;

            // Additionally recreate front end controller, because the old one uses the invalidated context.
            //   - to fully initialize the front end, we have to go through all the steps that have already been
            //     executed on the old controller; those steps are (1) InitializeHost, and (2) ParseConfig
            FrontEndController = m_frontEndControllerFactory.Create(Context.PathTable, Context.SymbolTable);
            FrontEndController.InitializeHost(Context.ToFrontEndContext(loggingContext), m_initialCommandLineConfiguration);
            FrontEndController.ParseConfig(m_initialCommandLineConfiguration);

            return(GraphReuseResult.CreateForPartialReuse(t.Item1, inputChanges));
        }
Пример #2
0
        private bool ConstructAndEvaluateGraph(
            LoggingContext loggingContext,
            FrontEndEngineAbstraction frontEndEngineAbstration,
            CacheInitializationTask engineCacheTask,
            MountsTable mountsTable,
            EvaluationFilter evaluationFilter,
            [CanBeNull] GraphReuseResult reuseResult,
            out PipGraph pipGraph)
        {
            Contract.Requires(frontEndEngineAbstration != null);
            Contract.Requires(engineCacheTask != null);
            Contract.Requires(mountsTable != null);

            pipGraph = null;
            IPipGraphBuilder pipGraphBuilder = null;

            if (!AddConfigurationMountsAndCompleteInitialization(loggingContext, mountsTable))
            {
                return(false);
            }

            IDictionary <ModuleId, MountsTable> moduleMountsTableMap;

            if (!mountsTable.PopulateModuleMounts(Configuration.ModulePolicies.Values, out moduleMountsTableMap))
            {
                Contract.Assume(loggingContext.ErrorWasLogged, "An error should have been logged after MountTable.PopulateModuleMounts()");
                return(false);
            }

            m_visualization?.MountsTable.MakeAvailable(mountsTable);

            if ((Configuration.Engine.Phase & EnginePhases.Schedule) != 0)
            {
                pipGraphBuilder = CreatePipGraphBuilder(loggingContext, mountsTable, reuseResult);
            }

            // Have to do some horrible magic here to get to a proper Task<T> with the BuildXL cache since
            // someone updated the engine cache to be an await style pattern, and there is no way to get to the EngineCache
            // If the cache was fast to startup, but perhaps blocked itself on first access we wouldn't have to do all these hoops.
            Func <Task <Possible <EngineCache> > > getBuildCacheTask =
                async() =>
            {
                return((await engineCacheTask).Then(engineCache => engineCache.CreateCacheForContext()));
            };

            if (!FrontEndController.PopulateGraph(
                    getBuildCacheTask(),
                    pipGraphBuilder,
                    frontEndEngineAbstration,
                    evaluationFilter,
                    Configuration,
                    m_initialCommandLineConfiguration.Startup))
            {
                LogFrontEndStats(loggingContext);

                Contract.Assume(loggingContext.ErrorWasLogged, "An error should have been logged after FrontEndController.PopulateGraph()");
                return(false);
            }

            LogFrontEndStats(loggingContext);

            // Pip graph must become immutable now that evaluation is done (required to construct a scheduler).
            return(pipGraphBuilder == null || (pipGraph = pipGraphBuilder.Build()) != null);
        }