Exemplo n.º 1
0
        /// <summary>
        /// Loads <see cref="FileChangeTracker"/>, and if successful, the <see cref="FileChangeTracker"/> is a disabled one.
        /// </summary>
        public static LoadingTrackerResult LoadTrackingChanges(
            LoggingContext loggingContext,
            VolumeMap volumeMap,
            IChangeJournalAccessor journal,
            string path,
            string buildEngineFingerprint,
            out FileChangeTracker tracker,
            bool loadForAllCapableVolumes = true)
        {
            Contract.Requires(!loadForAllCapableVolumes || volumeMap != null);
            Contract.Requires(!loadForAllCapableVolumes || journal != null);
            Contract.Requires(path != null);

            tracker = null;

            using (var pm = BuildXL.Tracing.PerformanceMeasurement.StartWithoutStatistic(
                       loggingContext,
                       loggingContext1 => Logger.Log.StartLoadingChangeTracker(loggingContext1, path),
                       loggingContext1 => Logger.Log.EndLoadingChangeTracker(loggingContext1)))
            {
                // Note that TryLoad may throw in the event of spooky I/O errors.
                var loadingTrackerResult = TryLoad(
                    pm.LoggingContext,
                    path,
                    volumeMap,
                    journal,
                    buildEngineFingerprint,
                    loadForAllCapableVolumes: loadForAllCapableVolumes);

                if (loadingTrackerResult.Succeeded)
                {
                    Contract.Assert(loadingTrackerResult.ChangeTrackingSet != null);

                    tracker = new FileChangeTracker(
                        pm.LoggingContext,
                        loadingTrackerResult.FileId,
                        FileChangeTrackingState.TrackingChanges,
                        loadingTrackerResult.ChangeTrackingSet.VolumeMap,
                        journal ?? new InProcChangeJournalAccessor(),
                        loadingTrackerResult.ChangeTrackingSet,
                        buildEngineFingerprint);
                }
                else
                {
                    Contract.Assert(loadingTrackerResult.ChangeTrackingSet == null);
                }

                Logger.Log.LoadingChangeTracker(
                    pm.LoggingContext,
                    path,
                    loadingTrackerResult.FileId.ToString(),
                    loadingTrackerResult.Status.ToString(),
                    loadingTrackerResult.StatusAsString,
                    loadingTrackerResult.TrackedVolumesCount,
                    (long)loadingTrackerResult.TrackedJournalsSizeBytes,
                    loadingTrackerResult.DurationMs);

                return(loadingTrackerResult);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates a new change tracker in the <see cref="FileChangeTrackingState.BuildingInitialChangeTrackingSet"/> state.
        /// The caller may then add tracking for full set of files of interest, for later re-use by
        /// <see cref="ResumeTrackingChanges(LoggingContext,BuildXL.Utilities.FileEnvelopeId,VolumeMap,IChangeJournalAccessor,FileChangeTrackingSet,string)"/>.
        /// </summary>
        public static FileChangeTracker StartTrackingChanges(
            LoggingContext loggingContext,
            VolumeMap volumeMap,
            IChangeJournalAccessor journal,
            string buildEngineFingerprint,
            FileEnvelopeId?correlatedId = default)
        {
            Contract.Requires(loggingContext != null);
            Contract.Requires(volumeMap != null);
            Contract.Requires(journal != null);
            Contract.Ensures(Contract.Result <FileChangeTracker>().TrackingState == FileChangeTrackingState.BuildingInitialChangeTrackingSet);

            var tracker = new FileChangeTracker(
                loggingContext,
                correlatedId ?? FileEnvelopeId.Create(),
                FileChangeTrackingState.BuildingInitialChangeTrackingSet,
                volumeMap,
                journal,
                FileChangeTrackingSet.CreateForAllCapableVolumes(loggingContext, volumeMap, journal),
                buildEngineFingerprint);

            foreach (var gvfsProjectionFile in volumeMap.GvfsProjections)
            {
                var maybeTracking = tracker.TryProbeAndTrackPath(gvfsProjectionFile);
                if (!maybeTracking.Succeeded)
                {
                    Logger.Log.TrackChangesToGvfsProjectionFailed(loggingContext, gvfsProjectionFile, maybeTracking.Failure.DescribeIncludingInnerFailures());
                }
            }

            return(tracker);
        }
        /// <summary>
        /// Creates a new file change tracking filter
        /// </summary>
        public FileChangeTrackingSelector(
            PathTable pathTable,
            LoggingContext loggingContext,
            IFileChangeTrackingSubscriptionSource tracker,
            IEnumerable <AbsolutePath> includedRoots,
            IEnumerable <AbsolutePath> excludedRoots)
        {
            Contract.Requires(pathTable != null);
            Contract.Requires(tracker != null);
            Contract.Requires(includedRoots != null);
            Contract.Requires(excludedRoots != null);

            m_semanticPathInfoMap = new FlaggedHierarchicalNameDictionary <bool>(pathTable, HierarchicalNameTable.NameFlags.Root);
            m_tracker             = tracker;
            m_disabledTracker     = FileChangeTracker.CreateDisabledTracker(loggingContext);

            foreach (var excludedRoot in excludedRoots)
            {
                if (m_semanticPathInfoMap.TryAdd(excludedRoot.Value, false))
                {
                    m_hasExcludedRoots = true;
                }
            }

            foreach (var includedRoot in includedRoots)
            {
                if (m_semanticPathInfoMap.TryAdd(includedRoot.Value, true))
                {
                    m_hasIncludedRoots = true;
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Tries to load a <see cref="FileChangeTrackingSet"/> and resume tracking changes.
        /// If loading is successful (including matching the provided atomic save token), the returned tracker begins in the <see cref="FileChangeTrackingState.TrackingChanges"/> state.
        /// The caller may then query for new changes since the tracking set was last checkpointed and persisted, and may track additional files.
        /// Otherwise, a tracker with a new and empty change tracking set is created, initially in the <see cref="FileChangeTrackingState.BuildingInitialChangeTrackingSet"/> state.
        /// In that case, attempting to query changes will fail (the caller should fall back to doing complete rather than incremental work, thus populating the new change tracking set).
        /// </summary>
        /// <exception cref="BuildXLException">Thrown in the event of an I/O error other than the given path being absent.</exception>
        public static LoadingTrackerResult ResumeOrRestartTrackingChanges(
            LoggingContext loggingContext,
            VolumeMap volumeMap,
            IChangeJournalAccessor journal,
            string path,
            string buildEngineFingerprint,
            out FileChangeTracker tracker)
        {
            Contract.Requires(volumeMap != null);
            Contract.Requires(journal != null);
            Contract.Requires(path != null);

            using (var pm = BuildXL.Tracing.PerformanceMeasurement.StartWithoutStatistic(
                       loggingContext,
                       loggingContext1 => Logger.Log.StartLoadingChangeTracker(loggingContext1, path),
                       loggingContext1 => Logger.Log.EndLoadingChangeTracker(loggingContext1)))
            {
                // Note that TryLoad may throw in the event of spooky I/O errors.
                var loadingTrackerResult = TryLoad(pm.LoggingContext, path, volumeMap, journal, buildEngineFingerprint);

                if (loadingTrackerResult.Succeeded)
                {
                    Contract.Assert(loadingTrackerResult.ChangeTrackingSet != null);

                    // Ideally, we reload prior state so that the caller can query changes and do incremental work.
                    // In this case, we already validated the correlating atomic save token, and so the state is safe to reuse.
                    tracker = ResumeTrackingChanges(
                        pm.LoggingContext,
                        loadingTrackerResult.FileId,
                        volumeMap,
                        journal,
                        loadingTrackerResult.ChangeTrackingSet,
                        buildEngineFingerprint);
                }
                else
                {
                    Contract.Assert(loadingTrackerResult.ChangeTrackingSet == null);

                    // Or, we might be unable to re-use the persisted state. In that case we start over. Note that there's nothing to do with the correlating save token here;
                    // on save, a new or existing token will be provided as appropriate.
                    // The reason of the failure is already logged in the TryLoad() method above.
                    tracker = StartTrackingChanges(pm.LoggingContext, volumeMap, journal, buildEngineFingerprint);
                }

                Logger.Log.LoadingChangeTracker(
                    pm.LoggingContext,
                    path,
                    loadingTrackerResult.FileId.ToString(),
                    loadingTrackerResult.Status.ToString(),
                    loadingTrackerResult.StatusAsString,
                    loadingTrackerResult.TrackedVolumesCount,
                    (long)loadingTrackerResult.TrackedJournalsSizeBytes,
                    loadingTrackerResult.DurationMs);

                return(loadingTrackerResult);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Creates an instance of <see cref="FileChangeProcessor"/>.
        /// </summary>
        public FileChangeProcessor(LoggingContext loggingContext, FileChangeTracker fileChangeTracker)
        {
            Contract.Requires(loggingContext != null);
            Contract.Requires(fileChangeTracker != null);
            Contract.Requires(fileChangeTracker.IsTrackingChanges);

            m_loggingContext    = loggingContext;
            m_fileChangeTracker = fileChangeTracker;
        }
Exemplo n.º 6
0
        /// <summary>
        /// Creates an instance of <see cref="FileChangeProcessor"/>.
        /// </summary>
        public FileChangeProcessor(
            LoggingContext loggingContext,
            FileChangeTracker fileChangeTracker,
            InputChangeList inputChangeList = null)
        {
            Contract.Requires(loggingContext != null);
            Contract.Requires(fileChangeTracker != null);
            Contract.Requires(fileChangeTracker.IsTrackingChanges);

            m_loggingContext    = loggingContext;
            m_fileChangeTracker = fileChangeTracker;
            m_inputChangeList   = inputChangeList;
        }