internal static Command InternalDeserialize(BinaryReader reader)
        {
            string dropName   = reader.ReadString();
            int    entryCount = reader.ReadInt32();

            BuildManifestEntry[] buildManifestEntries = Enumerable
                                                        .Range(0, entryCount)
                                                        .Select(i => BuildManifestEntry.Deserialize(reader))
                                                        .ToArray();

            return(new RegisterFilesForBuildManifestCommand(dropName, buildManifestEntries));
        }
        /// <inheritdoc />
        public override bool TryParseResult(string result, out BuildManifestEntry[] commandResult)
        {
            try
            {
                using (var stream = new MemoryStream(Convert.FromBase64String(result)))
                    using (var reader = new BinaryReader(stream))
                    {
                        var length = reader.ReadInt32();
                        commandResult = Enumerable.Range(0, length).Select(_ => BuildManifestEntry.Deserialize(reader)).ToArray();
                        return(true);
                    }
            }
            catch
            {
#pragma warning disable ERP022 // Unobserved exception in generic exception handler
                commandResult = new BuildManifestEntry[0];
                return(false);

#pragma warning restore ERP022 // Unobserved exception in generic exception handler
            }
        }
Exemple #3
0
        /// <summary>
        /// Returns an invalid <see cref="Tracing.BuildManifestEntry"/> when file read or hash computation fails.
        /// Else returns a valid <see cref="Tracing.BuildManifestEntry"/> on success.
        /// </summary>
        private async Task <Tracing.BuildManifestEntry> ExecuteRecordBuildManifestHashWithXlgAsync(string dropName, BuildManifestEntry buildManifestEntry)
        {
            await Task.Yield(); // Yield to ensure hashing happens asynchronously

            // (1) Attempt hash read from in-memory store
            if (m_inMemoryBuildManifestStore.TryGetValue(buildManifestEntry.Hash, out var buildManifestHash))
            {
                return(new Tracing.BuildManifestEntry(dropName, buildManifestEntry.RelativePath, buildManifestEntry.Hash, buildManifestHash));
            }

            // (2) Attempt hash read from cache
            if (TryGetBuildManifestHashesAsync(buildManifestEntry.Hash, out var buildManifestHashes))
            {
                m_inMemoryBuildManifestStore.TryAdd(buildManifestEntry.Hash, buildManifestHashes);
                return(new Tracing.BuildManifestEntry(dropName, buildManifestEntry.RelativePath, buildManifestEntry.Hash, buildManifestHashes));
            }

            // (3) Attempt to compute hash for locally existing file (Materializes non-existing files)
            using (ManifestCounters.StartStopwatch(BuildManifestCounters.InternalComputeHashLocallyDuration))
            {
                ManifestCounters.IncrementCounter(BuildManifestCounters.InternalComputeHashLocallyCount);
                var computeHashResult = await ComputeBuildManifestHashFromCacheAsync(buildManifestEntry, requestedTypes : ContentHashingUtilities.BuildManifestHashTypes);

                if (computeHashResult.Succeeded)
                {
                    m_inMemoryBuildManifestStore.TryAdd(buildManifestEntry.Hash, computeHashResult.Result);
                    StoreBuildManifestHashes(buildManifestEntry.Hash, computeHashResult.Result);
                    return(new Tracing.BuildManifestEntry(dropName, buildManifestEntry.RelativePath, buildManifestEntry.Hash, computeHashResult.Result));
                }

                Tracing.Logger.Log.ErrorApiServerGetBuildManifestHashFromLocalFileFailed(m_loggingContext, buildManifestEntry.Hash.Serialize(), computeHashResult.Failure.DescribeIncludingInnerFailures());
            }

            ManifestCounters.IncrementCounter(BuildManifestCounters.TotalHashFileFailures);
            return(new Tracing.BuildManifestEntry(dropName, buildManifestEntry.RelativePath, buildManifestEntry.Hash, new[] { new ContentHash(HashType.Unknown) }));
        }
Exemple #4
0
        /// <summary>
        /// Compute the hashes for file stored in Cache. Required for Build Manifest generation.
        /// </summary>
        private async Task <Possible <IReadOnlyList <ContentHash> > > ComputeBuildManifestHashFromCacheAsync(BuildManifestEntry buildManifestEntry, IList <HashType> requestedTypes)
        {
            // Ensure that the file is materialized.
            MaterializeFileCommand materializeCommand = new MaterializeFileCommand(buildManifestEntry.Artifact, buildManifestEntry.FullFilePath);
            IIpcResult             materializeResult  = await ExecuteMaterializeFileAsync(materializeCommand);

            if (!materializeResult.Succeeded)
            {
                return(new Failure <string>($"Unable to materialize file: '{buildManifestEntry.FullFilePath}' with hash: '{buildManifestEntry.Hash.Serialize()}'. Failure: {materializeResult.Payload}"));
            }

            return(await TryGetBuildManifestHashFromLocalFileAsync(buildManifestEntry.FullFilePath, buildManifestEntry.Hash, requestedTypes));
        }
Exemple #5
0
        /// <summary>
        /// Returns the BuildManifestEntry when hash read/computation fails. Else returns null.
        /// </summary>
        private async Task <BuildManifestEntry> ExecuteRecordBuildManifestHashAsync(string dropName, BuildManifestEntry buildManifestEntry)
        {
            await Task.Yield(); // Yield to ensure hashing happens asynchronously

            // (1) Attempt hash read from in-memory store
            if (m_inMemoryBuildManifestStore.TryGetValue(buildManifestEntry.Hash, out var buildManifestHash))
            {
                RecordFileForBuildManifestInXLG(dropName, buildManifestEntry.RelativePath, buildManifestEntry.Hash, buildManifestHash);
                return(null);
            }

            // (2) Attempt hash read from cache
            ContentHash?hashFromCache = await TryGetBuildManifestHashAsync(buildManifestEntry.Hash);

            if (hashFromCache.HasValue)
            {
                m_inMemoryBuildManifestStore.TryAdd(buildManifestEntry.Hash, hashFromCache.Value);
                RecordFileForBuildManifestInXLG(dropName, buildManifestEntry.RelativePath, buildManifestEntry.Hash, hashFromCache.Value);
                return(null);
            }

            // (3) Attempt to compute hash for locally existing file (Materializes non-existing files)
            var computeHashResult = await ComputeBuildManifestHashFromCacheAsync(buildManifestEntry);

            if (computeHashResult.Succeeded)
            {
                m_inMemoryBuildManifestStore.TryAdd(buildManifestEntry.Hash, computeHashResult.Result);
                RecordFileForBuildManifestInXLG(dropName, buildManifestEntry.RelativePath, buildManifestEntry.Hash, computeHashResult.Result);
                await StoreBuildManifestHashAsync(buildManifestEntry.Hash, computeHashResult.Result);

                return(null);
            }

            Tracing.Logger.Log.ErrorApiServerGetBuildManifestHashFromCacheFailed(m_loggingContext, buildManifestEntry.Hash.Serialize(), computeHashResult.Failure.DescribeIncludingInnerFailures());
            return(buildManifestEntry);
        }
Exemple #6
0
        /// <summary>
        /// Compute the SHA-256 hash for file stored in Cache. Required for Build Manifets generation.
        /// </summary>
        private async Task <Possible <ContentHash> > ComputeBuildManifestHashFromCacheAsync(BuildManifestEntry buildManifestEntry)
        {
            if (!File.Exists(buildManifestEntry.FullFilePath))
            {
                // Ensure file is materialized locally
                if (!AbsolutePath.TryCreate(m_context.PathTable, buildManifestEntry.FullFilePath, out AbsolutePath path))
                {
                    return(new Failure <string>($"Invalid absolute path: '{buildManifestEntry.FullFilePath}'"));
                }

                MaterializeFileCommand materializeCommand = new MaterializeFileCommand(FileArtifact.CreateOutputFile(path), buildManifestEntry.FullFilePath);
                IIpcResult             materializeResult  = await ExecuteMaterializeFileAsync(materializeCommand);

                if (!materializeResult.Succeeded)
                {
                    return(new Failure <string>($"Unable to materialize file: '{buildManifestEntry.FullFilePath}' with hash: '{buildManifestEntry.Hash.Serialize()}'. Failure: {materializeResult.Payload}"));
                }
            }

            return(await TryGetBuildManifestHashFromLocalFileAsync(buildManifestEntry.FullFilePath));
        }