Ejemplo n.º 1
0
        /// <summary>
        /// Because pinning requires recursing an entire tree, we need to limit the number of simultaneous calls to DedupStore.
        /// </summary>
        protected async Task <TResult> TryGatedArtifactOperationAsync <TResult>(
            Context context, string content, string operationName, Func <CancellationToken, Task <TResult> > func, CancellationToken token, [CallerMemberName] string caller = null)
        {
            var sw = Stopwatch.StartNew();
            await ConnectionGate.WaitAsync(token);

            var elapsed = sw.Elapsed;

            if (elapsed.TotalSeconds >= MinLogWaitTimeInSeconds)
            {
                Tracer.Warning(context, $"Operation '{caller}' for {content} was throttled for {elapsed.TotalSeconds}sec");
            }

            try
            {
                return(await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                           context,
                           operationName,
                           innerCts => func(innerCts),
                           token));
            }
            finally
            {
                ConnectionGate.Release();
            }
        }
Ejemplo n.º 2
0
        private async Task <Uri?> GetUriAsync(OperationContext context, ContentHash contentHash)
        {
            if (!DownloadUriCache.Instance.TryGetDownloadUri(contentHash, out var uri))
            {
                _blobCounters[Counters.VstsDownloadUriFetchedFromRemote].Increment();
                var blobId = BuildXL.Cache.ContentStore.Hashing.BlobIdentifierHelperExtensions.ToBlobIdentifier(contentHash);

                var mappings = await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                    context,
                    "GetStreamInternal",
                    innerCts => BlobStoreHttpClient.GetDownloadUrisAsync(
                        new[] { ToVstsBlobIdentifier(blobId) },
                        EdgeCache.NotAllowed,
                        cancellationToken: innerCts),
                    context.Token).ConfigureAwait(false);

                if (mappings == null || !mappings.TryGetValue(ToVstsBlobIdentifier(blobId), out uri))
                {
                    return(null);
                }

                DownloadUriCache.Instance.AddDownloadUri(contentHash, uri);
            }
            else
            {
                _blobCounters[Counters.VstsDownloadUriFetchedInMemory].Increment();
            }

            return(uri.NotNullUri);
        }
Ejemplo n.º 3
0
        private async Task <IEnumerable <Task <Indexed <PinResult> > > > UpdateBlobStoreAsync(OperationContext context, IReadOnlyList <ContentHash> contentHashes, DateTime endDateTime)
        {
            // Convert missing content hashes to blob Ids
            var blobIds = contentHashes.Select(c => ToVstsBlobIdentifier(BuildXL.Cache.ContentStore.Hashing.BlobIdentifierHelperExtensions.ToBlobIdentifier(c))).ToList();

            // Call TryReference on the blob ids
            var references = blobIds.Distinct().ToDictionary(
                blobIdentifier => blobIdentifier,
                _ => (IEnumerable <BlobReference>) new[] { new BlobReference(endDateTime) });

            // TODO: In groups of 1000 (bug 1365340)
            var referenceResults = await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                context,
                "UpdateBlobStore",
                innerCts => BlobStoreHttpClient.TryReferenceAsync(references, cancellationToken: innerCts),
                context.Token).ConfigureAwait(false);

            // There's 1-1 mapping between given content hashes and blob ids
            var remoteResults = blobIds
                                .Select((blobId, i) =>
            {
                var pinResult = referenceResults.ContainsKey(blobId)
                        ? PinResult.ContentNotFound
                        : PinResult.Success;
                if (pinResult.Succeeded)
                {
                    BackingContentStoreExpiryCache.Instance.AddExpiry(contentHashes[i], endDateTime);
                    _counters[BackingContentStore.SessionCounters.PinSatisfiedFromRemote].Increment();
                }

                return(pinResult.WithIndex(i));
            });

            return(remoteResults.AsTasks());
        }
Ejemplo n.º 4
0
        private async Task <Stream?> GetStreamInternalAsync(OperationContext context, ContentHash contentHash, int?overrideStreamMinimumReadSizeInBytes)
        {
            Uri?azureBlobUri = default;

            try
            {
                if (_downloadBlobsThroughBlobStore)
                {
                    return(await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                               context,
                               "GetStreamInternalThroughBlobStore",
                               innerCts => BlobStoreHttpClient.GetBlobAsync(ToVstsBlobIdentifier(contentHash.ToBlobIdentifier()), cancellationToken: innerCts),
                               context.Token).ConfigureAwait(false));
                }
                else
                {
                    if (!DownloadUriCache.Instance.TryGetDownloadUri(contentHash, out var uri))
                    {
                        _blobCounters[Counters.VstsDownloadUriFetchedFromRemote].Increment();
                        var blobId = contentHash.ToBlobIdentifier();

                        var mappings = await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                            context,
                            "GetStreamInternal",
                            innerCts => BlobStoreHttpClient.GetDownloadUrisAsync(
                                new[] { ToVstsBlobIdentifier(blobId) },
                                EdgeCache.NotAllowed,
                                cancellationToken: innerCts),
                            context.Token).ConfigureAwait(false);

                        if (mappings == null || !mappings.TryGetValue(ToVstsBlobIdentifier(blobId), out uri))
                        {
                            return(null);
                        }

                        DownloadUriCache.Instance.AddDownloadUri(contentHash, uri);
                    }
                    else
                    {
                        _blobCounters[Counters.VstsDownloadUriFetchedInMemory].Increment();
                    }

                    azureBlobUri = uri.NotNullUri;
                    return(await GetStreamThroughAzureBlobs(
                               uri.NotNullUri,
                               overrideStreamMinimumReadSizeInBytes,
                               _parallelSegmentDownloadConfig.SegmentDownloadTimeout,
                               context.Token).ConfigureAwait(false));
                }
            }
            catch (Exception e)
            {
                TraceException(context, contentHash, azureBlobUri, e);
                throw;
            }
        }
Ejemplo n.º 5
0
        private async Task <Stream> GetStreamInternalAsync(Context context, ContentHash contentHash, int?overrideStreamMinimumReadSizeInBytes, CancellationToken cts)
        {
            if (_downloadBlobsThroughBlobStore)
            {
                return(await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                           context,
                           "GetStreamInternalThroughBlobStore",
                           innerCts => BlobStoreHttpClient.GetBlobAsync(ToVstsBlobIdentifier(contentHash.ToBlobIdentifier()), cancellationToken: innerCts),
                           cts).ConfigureAwait(false));
            }
            else
            {
                PreauthenticatedUri uri;
                if (!DownloadUriCache.Instance.TryGetDownloadUri(contentHash, out uri))
                {
                    Tracer.RecordDownloadUriFetchedFromRemote();
                    BlobIdentifier blobId = contentHash.ToBlobIdentifier();

                    IDictionary <VstsBlobIdentifier, PreauthenticatedUri> mappings = await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                        context,
                        "GetStreamInternal",
                        innerCts => BlobStoreHttpClient.GetDownloadUrisAsync(
                            new[] { ToVstsBlobIdentifier(blobId) },
                            EdgeCache.NotAllowed,
                            cancellationToken: innerCts),
                        cts).ConfigureAwait(false);

                    if (mappings == null || !mappings.TryGetValue(ToVstsBlobIdentifier(blobId), out uri))
                    {
                        return(null);
                    }

                    DownloadUriCache.Instance.AddDownloadUri(contentHash, uri);
                }
                else
                {
                    Tracer.RecordDownloadUriFetchedFromCache();
                }

                return(await GetStreamThroughAzureBlobs(
                           uri.NotNullUri,
                           overrideStreamMinimumReadSizeInBytes,
                           _parallelSegmentDownloadConfig.SegmentDownloadTimeout,
                           cts).ConfigureAwait(false));
            }
        }