Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,12 @@ internal sealed partial class FeedManager : IDisposable
/// </summary>
public ImmutableHashSet<string> InheritedFeeds => AllFeeds.Except(ExplicitFeeds).ToImmutableHashSet();

private readonly Lazy<(bool, ImmutableHashSet<string>)> lazyReachableExplicitFeeds;

/// <summary>
/// Gets whether there was a timeout when checking the reachability of the explicitly configured NuGet feeds.
/// </summary>
public bool ExplicitFeedTimeout => lazyReachableExplicitFeeds.Value.Item1;
private readonly Lazy<ImmutableHashSet<string>> lazyReachableExplicitFeeds;

/// <summary>
/// Gets the list of reachable NuGet feeds that are explicitly configured.
/// </summary>
public ImmutableHashSet<string> ReachableExplicitFeeds => lazyReachableExplicitFeeds.Value.Item2;
public ImmutableHashSet<string> ReachableExplicitFeeds => lazyReachableExplicitFeeds.Value;

private readonly Lazy<ImmutableHashSet<string>> lazyReachableFeeds;
/// <summary>
Expand All @@ -96,15 +91,11 @@ public FeedManager(ILogger logger, IDotNet dotnet, DependabotProxy? dependabotPr

lazyExplicitFeeds = new Lazy<ImmutableHashSet<string>>(GetExplicitFeeds);
lazyAllFeeds = new Lazy<ImmutableHashSet<string>>(GetAllFeeds);
lazyReachableExplicitFeeds = new Lazy<(bool, ImmutableHashSet<string>)>(() =>
{
var timeout = CheckSpecifiedFeeds(ExplicitFeeds, out var reachableFeeds);
return (timeout, reachableFeeds);
});
lazyReachableExplicitFeeds = new Lazy<ImmutableHashSet<string>>(() => CheckSpecifiedFeeds(ExplicitFeeds));
lazyReachableFeeds = new Lazy<ImmutableHashSet<string>>(() =>
{
// Inherited feeds should only be used, if they are indeed reachable (as they may be environment specific).
CheckSpecifiedFeeds(InheritedFeeds, out var reachableInheritedFeeds);
var reachableInheritedFeeds = CheckSpecifiedFeeds(InheritedFeeds);
return ReachableExplicitFeeds.Union(reachableInheritedFeeds).ToImmutableHashSet();
});
lazyReachableFallbackFeeds = new Lazy<ImmutableHashSet<string>>(() =>
Expand Down Expand Up @@ -271,7 +262,7 @@ private static async Task<HttpResponseMessage> ExecuteGetRequest(string address,
return await httpClient.GetAsync(address, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
}

private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, out bool isTimeout)
private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount)
{
logger.LogInfo($"Checking if NuGet feed '{feed}' is reachable...");

Expand Down Expand Up @@ -304,8 +295,6 @@ private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount,

using HttpClient client = new(httpClientHandler);

isTimeout = false;

for (var i = 0; i < tryCount; i++)
{
using var cts = new CancellationTokenSource();
Expand Down Expand Up @@ -335,7 +324,6 @@ private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount,
}

logger.LogWarning($"Didn't receive answer from NuGet feed '{feed}'. Tried it {tryCount} times.");
isTimeout = true;
return false;
}

Expand All @@ -359,12 +347,8 @@ private HashSet<string> GetExcludedFeeds()
/// Checks that we can connect to the specified NuGet feeds.
/// </summary>
/// <param name="feeds">The set of package feeds to check.</param>
/// <param name="reachableFeeds">The list of feeds that were reachable.</param>
/// <returns>
/// True if there is a timeout when trying to reach the feeds (excluding any feeds that are configured
/// to be excluded from the check) or false otherwise.
/// </returns>
private bool CheckSpecifiedFeeds(ImmutableHashSet<string> feeds, out ImmutableHashSet<string> reachableFeeds)
/// <returns>The list of feeds that were reachable.</returns>
private ImmutableHashSet<string> CheckSpecifiedFeeds(ImmutableHashSet<string> feeds)
{
// Exclude any feeds from the feed check that are configured by the corresponding environment variable.
// These feeds are always assumed to be reachable.
Expand All @@ -380,12 +364,10 @@ private bool CheckSpecifiedFeeds(ImmutableHashSet<string> feeds, out ImmutableHa
return true;
}).ToHashSet();

var reachable = GetReachableNuGetFeeds(feedsToCheck, isFallback: false, out var isTimeout);
var reachable = GetReachableNuGetFeeds(feedsToCheck, isFallback: false);

// Always consider feeds excluded for the reachability check as reachable.
reachableFeeds = reachable.Union(feeds.Where(feed => excludedFeeds.Contains(feed))).ToImmutableHashSet();

return isTimeout;
return reachable.Union(feeds.Where(feed => excludedFeeds.Contains(feed))).ToImmutableHashSet();
}

/// <summary>
Expand All @@ -398,7 +380,7 @@ public bool IsDefaultFeedReachable()
if (CheckNugetFeedResponsiveness)
{
var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback: false);
return IsFeedReachable(PublicNugetOrgFeed, initialTimeout, tryCount, out var _);
return IsFeedReachable(PublicNugetOrgFeed, initialTimeout, tryCount);
}

return true;
Expand All @@ -409,22 +391,15 @@ public bool IsDefaultFeedReachable()
/// </summary>
/// <param name="feedsToCheck">The feeds to check.</param>
/// <param name="isFallback">Whether the feeds are fallback feeds or not.</param>
/// <param name="isTimeout">Whether a timeout occurred while checking the feeds.</param>
/// <returns>The list of feeds that could be reached.</returns>
private List<string> GetReachableNuGetFeeds(HashSet<string> feedsToCheck, bool isFallback, out bool isTimeout)
private List<string> GetReachableNuGetFeeds(HashSet<string> feedsToCheck, bool isFallback)
{
var fallbackStr = isFallback ? "fallback " : "";
logger.LogInfo($"Checking {fallbackStr}NuGet feed reachability on feeds: {string.Join(", ", feedsToCheck.OrderBy(f => f))}");

var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback);
var timeout = false;
var reachableFeeds = feedsToCheck
.Where(feed =>
{
var reachable = IsFeedReachable(feed, initialTimeout, tryCount, out var feedTimeout);
timeout |= feedTimeout;
return reachable;
})
.Where(feed => IsFeedReachable(feed, initialTimeout, tryCount))
.ToList();

if (reachableFeeds.Count == 0)
Expand All @@ -436,7 +411,6 @@ private List<string> GetReachableNuGetFeeds(HashSet<string> feedsToCheck, bool i
logger.LogInfo($"Reachable {fallbackStr}NuGet feeds: {string.Join(", ", reachableFeeds.OrderBy(f => f))}");
}

isTimeout = timeout;
return reachableFeeds;
}

Expand All @@ -460,7 +434,7 @@ private List<string> GetReachableFallbackNugetFeeds()
}
}

return GetReachableNuGetFeeds(fallbackFeeds, isFallback: true, out var _);
return GetReachableNuGetFeeds(fallbackFeeds, isFallback: true);
}

private ImmutableHashSet<string> GetExplicitFeeds()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,6 @@ public HashSet<AssemblyLookupLocation> Restore()

var allExplicitReachable = explicitFeeds.Count == feedManager.ReachableExplicitFeeds.Count;
EmitUnreachableFeedsDiagnostics(allExplicitReachable);

if (feedManager.ExplicitFeedTimeout)
{
// If we experience a timeout, we use this fallback.
// todo: we could also check the reachability of the inherited nuget feeds, but to use those in the fallback we would need to handle authentication too.
var unresponsiveMissingPackageLocation = DownloadMissingPackages([]);
return unresponsiveMissingPackageLocation is null
? []
: [unresponsiveMissingPackageLocation];
}

}

try
Expand Down Expand Up @@ -625,14 +614,6 @@ public void Dispose()
feedManager.Dispose();
}

/// <summary>
/// Returns the full path to a temporary directory with the given subfolder name.
/// </summary>
private static string ComputeTempDirectoryPath(string subfolderName)
{
return Path.Join(FileUtils.GetTemporaryWorkingDirectory(out _), subfolderName);
}

/// <summary>
/// Computes a unique temporary directory path based on the source directory and the subfolder name.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
| All NuGet feeds reachable | 0.0 |
| Failed project restore with missing package error | 1.0 |
| Failed project restore with package source error | 0.0 |
| Failed solution restore with missing package error | 0.0 |
| Failed solution restore with package source error | 0.0 |
| Fallback nuget restore | 1.0 |
| Inherited NuGet feed count | 1.0 |
| NuGet feed responsiveness checked | 1.0 |
Expand All @@ -7,10 +11,13 @@
| Resolved assembly conflicts | 7.0 |
| Resource extraction enabled | 0.0 |
| Restored .NET framework variants | 0.0 |
| Restored projects through solution files | 0.0 |
| Solution files on filesystem | 1.0 |
| Source files generated | 0.0 |
| Source files on filesystem | 1.0 |
| Successfully ran fallback nuget restore | 1.0 |
| Successfully restored project files | 0.0 |
| Successfully restored solution files | 1.0 |
| Unresolved references | 0.0 |
| UseWPF set | 0.0 |
| UseWindowsForms set | 0.0 |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
| All NuGet feeds reachable | 0.0 |
| Failed project restore with missing package error | 1.0 |
| Failed project restore with package source error | 0.0 |
| Failed solution restore with missing package error | 0.0 |
| Failed solution restore with package source error | 0.0 |
| Fallback nuget restore | 1.0 |
| Inherited NuGet feed count | 1.0 |
| NuGet feed responsiveness checked | 1.0 |
Expand All @@ -7,10 +11,13 @@
| Resolved assembly conflicts | 7.0 |
| Resource extraction enabled | 0.0 |
| Restored .NET framework variants | 0.0 |
| Restored projects through solution files | 0.0 |
| Solution files on filesystem | 1.0 |
| Source files generated | 0.0 |
| Source files on filesystem | 1.0 |
| Successfully ran fallback nuget restore | 1.0 |
| Successfully restored project files | 0.0 |
| Successfully restored solution files | 1.0 |
| Unresolved references | 0.0 |
| UseWPF set | 0.0 |
| UseWindowsForms set | 0.0 |
Expand Down
Loading