예제 #1
0
        private async Task <NupkgEntry> OpenNupkgStreamAsyncCore(PackageInfo package, CancellationToken cancellationToken)
        {
            for (var retry = 0; retry != 3; ++retry)
            {
                try
                {
                    using (var data = await _httpSource.GetAsync(
                               new HttpSourceCachedRequest(
                                   package.ContentUri,
                                   "nupkg_" + package.Identity.Id + "." + package.Identity.Version,
                                   CreateCacheContext(retry))
                    {
                        EnsureValidContents = stream => HttpStreamValidation.ValidateNupkg(package.ContentUri, stream)
                    },
                               Logger,
                               cancellationToken))
                    {
                        return(new NupkgEntry
                        {
                            TempFileName = data.CacheFileName
                        });
                    }
                }
                catch (TaskCanceledException) when(retry < 2)
                {
                    // Requests can get cancelled if we got the data from elsewhere, no reason to warn.
                    string message = string.Format(CultureInfo.CurrentCulture, Strings.Log_CanceledNupkgDownload, package.ContentUri);

                    Logger.LogMinimal(message);
                }
                catch (Exception ex)
                {
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_FailedToDownloadPackage, package.ContentUri)
                                  + Environment.NewLine
                                  + ExceptionUtilities.DisplayMessage(ex);
                    if (retry == 2)
                    {
                        Logger.LogError(message);
                    }
                    else
                    {
                        Logger.LogMinimal(message);
                    }
                }
            }

            return(null);
        }
예제 #2
0
        private async Task <T> ProcessHttpSourceResultAsync <T>(
            PackageIdentity identity,
            string url,
            Func <HttpSourceResult, Task <T> > processAsync,
            SourceCacheContext cacheContext,
            ILogger logger,
            CancellationToken token)
        {
            for (var retry = 0; retry < 3; ++retry)
            {
                var httpSourceCacheContext = HttpSourceCacheContext.Create(cacheContext, retry);

                try
                {
                    return(await _httpSource.GetAsync(
                               new HttpSourceCachedRequest(
                                   url,
                                   "nupkg_" + identity.Id.ToLowerInvariant() + "." + identity.Version.ToNormalizedString(),
                                   httpSourceCacheContext)
                    {
                        EnsureValidContents = stream => HttpStreamValidation.ValidateNupkg(url, stream),
                        IgnoreNotFounds = true,
                        MaxTries = 1
                    },
                               async httpSourceResult => await processAsync(httpSourceResult),
                               logger,
                               token));
                }
                catch (TaskCanceledException) when(retry < 2)
                {
                    // Requests can get cancelled if we got the data from elsewhere, no reason to warn.
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_CanceledNupkgDownload, url);

                    logger.LogMinimal(message);
                }
                catch (Exception ex) when(retry < 2)
                {
                    var message = string.Format(
                        CultureInfo.CurrentCulture,
                        Strings.Log_FailedToDownloadPackage,
                        identity,
                        url)
                                  + Environment.NewLine
                                  + ExceptionUtilities.DisplayMessage(ex);

                    logger.LogMinimal(message);
                }
                catch (Exception ex) when(retry == 2)
                {
                    var message = string.Format(
                        CultureInfo.CurrentCulture,
                        Strings.Log_FailedToDownloadPackage,
                        identity,
                        url)
                                  + Environment.NewLine
                                  + ExceptionUtilities.DisplayMessage(ex);

                    logger.LogError(message);
                }
            }

            return(await processAsync(null));
        }
예제 #3
0
        private async Task <T> ProcessHttpSourceResultAsync <T>(
            PackageIdentity identity,
            string url,
            Func <HttpSourceResult, Task <T> > processAsync,
            SourceCacheContext cacheContext,
            ILogger logger,
            CancellationToken token)
        {
            int maxRetries = _enhancedHttpRetryHelper.EnhancedHttpRetryEnabled ? _enhancedHttpRetryHelper.ExperimentalMaxNetworkTryCount : 3;

            for (var retry = 1; retry <= maxRetries; ++retry)
            {
                var httpSourceCacheContext = HttpSourceCacheContext.Create(cacheContext, isFirstAttempt: retry == 1);

                try
                {
                    return(await _httpSource.GetAsync(
                               new HttpSourceCachedRequest(
                                   url,
                                   "nupkg_" + identity.Id.ToLowerInvariant() + "." + identity.Version.ToNormalizedString(),
                                   httpSourceCacheContext)
                    {
                        EnsureValidContents = stream => HttpStreamValidation.ValidateNupkg(url, stream),
                        IgnoreNotFounds = true,
                        MaxTries = 1,
                        IsRetry = retry > 1,
                        IsLastAttempt = retry == maxRetries
                    },
                               async httpSourceResult => await processAsync(httpSourceResult),
                               logger,
                               token));
                }
                catch (TaskCanceledException) when(retry < maxRetries)
                {
                    // Requests can get cancelled if we got the data from elsewhere, no reason to warn.
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_CanceledNupkgDownload, url);

                    logger.LogMinimal(message);
                }
                catch (Exception ex) when(retry < maxRetries)
                {
                    var message = string.Format(
                        CultureInfo.CurrentCulture,
                        Strings.Log_FailedToDownloadPackage,
                        identity,
                        url)
                                  + Environment.NewLine
                                  + ExceptionUtilities.DisplayMessage(ex);

                    logger.LogMinimal(message);

                    if (_enhancedHttpRetryHelper.EnhancedHttpRetryEnabled &&
                        ex.InnerException != null &&
                        ex.InnerException is IOException &&
                        ex.InnerException.InnerException != null &&
                        ex.InnerException.InnerException is System.Net.Sockets.SocketException)
                    {
                        // An IO Exception with inner SocketException indicates server hangup ("Connection reset by peer").
                        // Azure DevOps feeds sporadically do this due to mandatory connection cycling.
                        // Stalling an extra <ExperimentalRetryDelayMilliseconds> gives Azure more of a chance to recover.
                        logger.LogVerbose("Enhanced retry: Encountered SocketException, delaying between tries to allow recovery");
                        await Task.Delay(TimeSpan.FromMilliseconds(_enhancedHttpRetryHelper.ExperimentalRetryDelayMilliseconds));
                    }
                }
                catch (Exception ex) when(retry == maxRetries)
                {
                    var message = string.Format(
                        CultureInfo.CurrentCulture,
                        Strings.Log_FailedToDownloadPackage,
                        identity,
                        url)
                                  + Environment.NewLine
                                  + ExceptionUtilities.DisplayMessage(ex);

                    logger.LogError(message);
                }
            }

            return(await processAsync(null));
        }