Пример #1
0
        /// <summary>
        /// Creates a new instance configured to output to the given writer.
        /// </summary>
        /// <param name="eventSource">
        /// The event source to listen to.
        /// </param>
        /// <param name="writer">The TextWriter where to send the output. Note that the writer will be disposed when the TextWriterEventListener is itself disposed.</param>
        /// <param name="baseTime">
        /// The UTC time representing time 0 for this listener.
        /// </param>
        /// <param name="warningMapper">
        /// An optional delegate that is used to map warnings into errors or to suppress warnings.
        /// </param>
        /// <param name="level">
        /// The base level of data to be sent to the listener.
        /// </param>
        /// <param name="timeDisplay">
        /// The kind of time prefix to apply to each chunk of output.
        /// </param>
        /// <param name="eventMask">
        /// If specified, an EventMask that allows selectively enabling or disabling events
        /// </param>
        /// <param name="onDisabledDueToDiskWriteFailure">
        /// If specified, called if the listener encounters a disk-write failure such as an out of space condition.
        /// Otherwise, such conditions will throw an exception.
        /// </param>
        /// <param name="pathTranslator">
        /// If specified, translates paths from one root to another
        /// </param>
        /// <param name="listenDiagnosticMessages">
        /// If true, all messages tagged with <see cref="Keywords.Diagnostics" /> at or above <paramref name="level"/> are enabled but not captured unless diagnostics are enabled per-task.
        /// This is useful for StatisticsEventListener, where you need to listen diagnostics messages but capture only ones tagged with CommonInfrastructure task.
        /// </param>
        public TextWriterEventListener(
            Events eventSource,
            IEventWriter writer,
            DateTime baseTime,
            WarningMapper warningMapper = null,
            EventLevel level            = EventLevel.Verbose,
            TimeDisplay timeDisplay     = TimeDisplay.None,
            EventMask eventMask         = null,
            DisabledDueToDiskWriteFailureEventHandler onDisabledDueToDiskWriteFailure = null,
            PathTranslator pathTranslator = null,
            bool listenDiagnosticMessages = false)
            : base(
                eventSource,
                baseTime,
                warningMapper,
                level,
                false,
                timeDisplay,
                eventMask,
                onDisabledDueToDiskWriteFailure,
                listenDiagnosticMessages)
        {
            Contract.Requires(eventSource != null);
            Contract.Requires(writer != null);

            m_writer = writer;

            m_flushTimer = new StoppableTimer(
                SynchronizedFlush,
                (int)s_flushInterval.TotalMilliseconds,
                (int)s_flushInterval.TotalMilliseconds);
            m_translator = pathTranslator;
        }
Пример #2
0
        /// <summary>
        /// Awaits for a given task while periodically calling <paramref name="action"/>.
        /// </summary>
        /// <typeparam name="TResult">Return type of the task</typeparam>
        /// <param name="task">The task to await</param>
        /// <param name="period">Period at which to call <paramref name="action"/></param>
        /// <param name="action">Action to periodically call.  The action receives elapsed time since this method was called.</param>
        /// <param name="reportImmediately">Whether <paramref name="action"/> should be called immediately.</param>
        /// <param name="reportAtEnd">Whether <paramref name="action"/> should be called at when </param>
        /// <returns>The result of the task.</returns>
        public static async Task <TResult> AwaitWithProgressReporting <TResult>(
            Task <TResult> task,
            TimeSpan period,
            Action <TimeSpan> action,
            bool reportImmediately = true,
            bool reportAtEnd       = true)
        {
            var startTime = DateTime.UtcNow;
            var timer     = new StoppableTimer(
                () =>
            {
                action(DateTime.UtcNow.Subtract(startTime));
            },
                dueTime: reportImmediately ? 0 : (int)period.TotalMilliseconds,
                period: (int)period.TotalMilliseconds);

            using (timer)
            {
                await task.ContinueWith(t =>
                {
                    return(timer.StopAsync());
                }).Unwrap();

                // report once at the end
                if (reportAtEnd)
                {
                    action(DateTime.UtcNow.Subtract(startTime));
                }

                return(await task);
            }
        }
Пример #3
0
        /// <summary>
        /// Awaits given tasks, periodically calling <paramref name="action"/>.
        /// </summary>
        /// <typeparam name="TItem">Type of the collection to iterate over.</typeparam>
        /// <typeparam name="TResult">Type of the tasks' result.</typeparam>
        /// <param name="collection">Collection to iterate over.</param>
        /// <param name="taskSelector">Function to use to select a task for a given item from the given collection.</param>
        /// <param name="action">
        /// Action to call periodically (as specified by <paramref name="period"/>).
        /// The action receives
        ///   (1) total elapsed time,
        ///   (2) all original items, and
        ///   (3) a collection of non-finished items
        /// </param>
        /// <param name="period">Period at which to call <paramref name="action"/>.</param>
        /// <returns>The results of inidvidual tasks.</returns>
        public static async Task <TResult[]> AwaitWithProgressReporting <TItem, TResult>(
            IReadOnlyCollection <TItem> collection,
            Func <TItem, Task <TResult> > taskSelector,
            Action <TimeSpan, IReadOnlyCollection <TItem>, IReadOnlyCollection <TItem> > action,
            TimeSpan period)
        {
            var startTime = DateTime.UtcNow;
            var timer     = new StoppableTimer(
                () =>
            {
                var elapsed        = DateTime.UtcNow.Subtract(startTime);
                var remainingItems = collection
                                     .Where(item => !taskSelector(item).IsCompleted)
                                     .ToList();
                action(elapsed, collection, remainingItems);
            },
                dueTime: 0,
                period: (int)period.TotalMilliseconds);

            using (timer)
            {
                var result = await Task.WhenAll(collection.Select(item => taskSelector(item)));

                await timer.StopAsync();

                // report once at the end
                action(DateTime.UtcNow.Subtract(startTime), collection, CollectionUtilities.EmptyArray <TItem>());
                return(result);
            }
        }
Пример #4
0
        public PulsationAnalyzePage()
        {
            InitializeComponent();

            Bluetooth = DependencyService.Get <Bluetooth>();

#if DEBUG
            _impulseInvoker = new MockImpulseInvoker();
#endif

            _vm    = new DeviceDataViewModel();
            _ddp   = DeviceDataProvider.GetProvider;
            _timer = new StoppableTimer(TimeSpan.FromMilliseconds(Constants.UPDATE_INTERVAL), TimerTick);
            FirstChanelSeries.ItemsSource  = _vm.FirstChanelSeriesData;
            SecondChanelSeries.ItemsSource = _vm.SecondChanelSeriesData;
            _jsonKeeper = new JsonDataKeeper <DeviceDataViewModel>();
        }
Пример #5
0
        private bool PersistFullBuild(IConfiguration configuration, PathTable pathTable, CancellationToken cancellationToken)
        {
            var snapshotFile = m_snapshotFile.ToString(pathTable);
            var mountFolder  = snapshotFile + ".tmpdir";

            try
            {
                // Find a drive to mount the VHD as for this process. The VHD will be mapped to a particular NTFS folder
                // and then mounted as a drive using the drive mapping functionality. This is done to avoid issues with MAX_PATH
                // issues since many codebases have paths nearing MAX_PATH which would go over if rooted in a subdirectory
                // of even a reasonably short path length.
                char unusedDrive       = char.MinValue;
                var  systemDriveLetter = SpecialFolderUtilities.SystemDirectory[0];
                for (char drive = 'A'; drive <= 'Z'; drive++)
                {
                    if (drive == systemDriveLetter || drive == 'C')
                    {
                        continue;
                    }

                    if (!AbsolutePath.TryGet(pathTable, new StringSegment(drive + @":\"), out _))
                    {
                        unusedDrive = drive;
                    }
                }

                if (unusedDrive == char.MinValue)
                {
                    Tracing.Logger.Log.GenericSnapshotError(m_loggingContext, "Snapshot error: Could not find unused drive to use for snapshot destination");
                    return(false);
                }

                bool mounted = VhdUtilities.Mount(snapshotFile, sizeMb: 1 << 20 /* 1 TB */, mountFolder: mountFolder);
                if (!mounted)
                {
                    Tracing.Logger.Log.GenericSnapshotError(
                        m_loggingContext,
                        I($"Snapshot error: Could not create VHD '{unusedDrive}' and mount at '{mountFolder}'"));
                    return(false);
                }

                // Map drive for mounted vhd in order to minimize chance of MAX_PATH issues copying files to VHD.
                bool mappingApplied =
                    ProcessNativeMethods.ApplyDriveMappings(new[] { new PathMapping(unusedDrive, Path.GetFullPath(mountFolder)) });
                if (!mappingApplied)
                {
                    Tracing.Logger.Log.GenericSnapshotError(
                        m_loggingContext,
                        I($"Snapshot error: Drive mapping could not be applied from '{unusedDrive}' to '{mountFolder}'"));
                    return(false);
                }

                var mountDriveRoot       = unusedDrive + @":\";
                var buildEvaluationFiles = new HashSet <AbsolutePath>(m_files);

                if (configuration.Cache.CacheConfigFile.IsValid)
                {
                    buildEvaluationFiles.Add(configuration.Cache.CacheConfigFile);
                }

                // Track used roots so mappings can be added for inputs and outputs when running BuildXL on snap
                ConcurrentDictionary <AbsolutePath, Unit> usedRoots = new ConcurrentDictionary <AbsolutePath, Unit>();

                int capturedFileCount = 0;
                int totalFileCount    = buildEvaluationFiles.Count + m_pipGraph.FileCount;

                Action updateStatus = () => { Console.WriteLine("Snapshot: {0} of {1} files captured", capturedFileCount, totalFileCount); };

                updateStatus();
                var t = new StoppableTimer(updateStatus, 5000, 5000);

                // Copy the build evaluation files
                Parallel.ForEach(
                    buildEvaluationFiles.ToArray(),
                    new ParallelOptions()
                {
                    MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = cancellationToken
                },
                    buildEvaluationFile =>
                {
                    usedRoots[buildEvaluationFile.GetRoot(pathTable)] = Unit.Void;
                    CopyPath(pathTable, buildEvaluationFile, mountDriveRoot);
                    Interlocked.Increment(ref capturedFileCount);
                });

                if (m_pipGraph != null)
                {
                    // Copy all source files
                    Parallel.ForEach(
                        m_pipGraph.AllFiles.ToArray(),
                        new ParallelOptions {
                        MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = cancellationToken
                    },
                        pipFile =>
                    {
                        try
                        {
                            usedRoots[pipFile.Path.GetRoot(pathTable)] = Unit.Void;
                            if (pipFile.IsOutputFile)
                            {
                                return;
                            }

                            if (!buildEvaluationFiles.Contains(pipFile.Path))
                            {
                                CopyPath(pathTable, pipFile.Path, mountDriveRoot);
                            }
                        }
                        finally
                        {
                            Interlocked.Increment(ref capturedFileCount);
                        }
                    });
                }

                // kill and wait for the status timer to die...
                t.Dispose();

                using (var writer = new StreamWriter(File.OpenWrite(Path.Combine(mountDriveRoot, "notes.txt"))))
                {
                    writer.WriteLine("Full Build Snapshot Info");
                    writer.WriteLine();
                    WriteNotes(configuration, pathTable, writer, path => path.ToString(pathTable));
                }

                using (var writer = new StreamWriter(File.OpenWrite(Path.Combine(mountDriveRoot, "runbxl.cmd"))))
                {
                    writer.Write("%BUILDXL_EXE_PATH% \"@%~dp0\\buildxl.rsp\" %*");
                    foreach (var usedRoot in usedRoots.Keys)
                    {
                        var usedRootLetter = usedRoot.ToString(pathTable)[0];
                        if (usedRootLetter.ToUpperInvariantFast() == 'C')
                        {
                            continue;
                        }

                        Directory.CreateDirectory(Path.Combine(mountDriveRoot, usedRootLetter.ToString()));
                        writer.Write(" /rootMap:{0}=\"%~dp0\\{0}\"", usedRootLetter);
                    }
                }

                using (var writer = new StreamWriter(File.OpenWrite(Path.Combine(mountDriveRoot, "buildxl.rsp"))))
                {
                    foreach (var argument in m_commandLineArguments)
                    {
                        writer.WriteLine(argument);
                    }

                    // Disable snapshot when running from snapshot
                    writer.WriteLine("/snapshotMode:None");

                    foreach (var envVar in m_environmentVariables)
                    {
                        writer.WriteLine("/envVar:{0}={1}", envVar.Key, envVar.Value ?? string.Empty);
                    }
                }
            }
            finally
            {
                Analysis.IgnoreResult(VhdUtilities.Dismount(snapshotFile, mountFolder));

                // TODO: Report error.
            }

            return(true);
        }
 public MockImpulseInvoker()
 {
     _dataProvider = DeviceDataProvider.GetProvider;
     _random       = new Random();
     _timer        = new StoppableTimer(TimeSpan.FromSeconds(1), Callback);
 }