Esempio n. 1
0
        public async Task ExceptionsShouldNotBlockProcessing()
        {
            int callbackCount = 0;
            var queue         = new ActionQueue(degreeOfParallelism: 2);

            try
            {
                await queue.ForEachAsync <int>(
                    Enumerable.Range(1, 5),
                    async (element, index) =>
                {
                    Interlocked.Increment(ref callbackCount);
                    await Task.Yield();
                    throw new Exception($"Failing item '{element}'.");
                }).WithTimeoutAsync(timeout: TimeSpan.FromSeconds(5));

                Assert.True(false, "ForEachAsync should fail.");
            }
            catch (TimeoutException)
            {
                Assert.True(false, "ForEachAsync got stuck");
            }
            catch (Exception e)
            {
                Assert.Equal(5, callbackCount);
                Assert.Contains("Failing item ", e.ToString());
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Takes a list of sealed directories, searches their contents for special manifest files, parses each of them to obtain
        /// a list of files to materialize, and finally requests from BuildXL's ApiServer to materialize them.
        /// </summary>
        private async Task <IIpcResult> RegisterManifestInternalAsync(ConfiguredCommand conf)
        {
            m_counters.IncrementCounter(MaterializationDaemonCounter.RegisterManifestRequestCount);

            var directoryPaths   = Directory.GetValues(conf.Config).ToArray();
            var directoryIds     = DirectoryId.GetValues(conf.Config).ToArray();
            var directoryFilters = DirectoryContentFilter.GetValues(conf.Config).ToArray();

            if (directoryPaths.Length != directoryIds.Length || directoryPaths.Length != directoryFilters.Length)
            {
                return(new IpcResult(
                           IpcResultStatus.GenericError,
                           I($"Directory counts don't match: #directories = {directoryPaths.Length}, #directoryIds = {directoryIds.Length}, #directoryFilters = {directoryFilters.Length}")));
            }

            if (ApiClient == null)
            {
                return(new IpcResult(IpcResultStatus.GenericError, "ApiClient is not initialized"));
            }

            var possibleFilters = InitializeFilters(directoryFilters);

            if (!possibleFilters.Succeeded)
            {
                return(new IpcResult(IpcResultStatus.ExecutionError, possibleFilters.Failure.Describe()));
            }

            var initializedFilters    = possibleFilters.Result;
            var possibleManifestFiles = await GetUniqueFilteredDirectoryContentAsync(directoryPaths, directoryIds, initializedFilters);

            if (!possibleManifestFiles.Succeeded)
            {
                return(new IpcResult(IpcResultStatus.ExecutionError, possibleManifestFiles.Failure.Describe()));
            }

            var           manifestFiles      = possibleManifestFiles.Result;
            var           sw                 = Stopwatch.StartNew();
            List <string> filesToMaterialize = null;

            try
            {
                // ensure that the manifest files are actually present on disk
                using (m_counters.StartStopwatch(MaterializationDaemonCounter.RegisterManifestFileMaterializationDuration))
                {
                    await m_actionQueue.ForEachAsync(
                        manifestFiles,
                        async (manifest, i) =>
                    {
                        m_counters.AddToCounter(MaterializationDaemonCounter.RegisterManifestFileMaterializationQueueDuration, sw.ElapsedMilliseconds);
                        await MaterializeFileAsync(manifest.Artifact, manifest.FileName, ignoreMaterializationFailures: false);
                    });
                }

                Possible <List <string> > possibleFiles;
                using (m_counters.StartStopwatch(MaterializationDaemonCounter.ManifestParsingOuterDuration))
                {
                    m_counters.AddToCounter(MaterializationDaemonCounter.ManifestParsingTotalFiles, possibleManifestFiles.Result.Count);
                    possibleFiles = await ParseManifestFilesAsync(manifestFiles);

                    if (!possibleFiles.Succeeded)
                    {
                        return(new IpcResult(IpcResultStatus.ExecutionError, possibleFiles.Failure.Describe()));
                    }

                    m_counters.AddToCounter(MaterializationDaemonCounter.ManifestParsingReferencedTotalFiles, possibleFiles.Result.Count);
                }

                filesToMaterialize = possibleFiles.Result;
                sw = Stopwatch.StartNew();
                using (m_counters.StartStopwatch(MaterializationDaemonCounter.RegisterManifestReferencedFileMaterializationDuration))
                {
                    await m_actionQueue.ForEachAsync(
                        filesToMaterialize,
                        async (file, i) =>
                    {
                        // Since these file paths are not real build artifacts (i.e., just strings constructed by a parser),
                        // they might not be "known" to BuildXL, and because of that, BuildXL won't be able to materialize them.
                        // Manifests are known to contain references to files that are not produced during a build, so we are
                        // ignoring materialization failures for such files. We are doing this so we won't fail IPC pips and
                        // a build could succeed.
                        // If there are real materialization errors (e.g., cache failure), the daemon relies on BuildXL logging
                        // the appropriate error events and failing the build.
                        m_counters.AddToCounter(MaterializationDaemonCounter.RegisterManifestReferencedFileMaterializationQueueDuration, sw.ElapsedMilliseconds);
                        await MaterializeFileAsync(FileArtifact.Invalid, file, ignoreMaterializationFailures: true);
                    });
                }
            }
            catch (Exception e)
            {
                return(new IpcResult(
                           IpcResultStatus.GenericError,
                           e.ToStringDemystified()));
            }

            // Note: we are not claiming here that all the files in filesToMaterialize were materialized cause we are ignoring materialization failures.
            // The real materialization status will be logged during execution of the Finalize command.
            return(IpcResult.Success(
                       $"Processed paths ({filesToMaterialize.Count}):{Environment.NewLine}{string.Join(Environment.NewLine, filesToMaterialize)}"));
        }