public async Task MirrorAsync(string id, CancellationToken cancellationToken) { if (await _localPackages.ExistsAsync(id)) { return; } _logger.LogInformation("Package {PackageId} does not exist locally. Mirroring...", id); var versions = await _upstreamFeed.GetAllVersionsAsync(id, includeUnlisted : true); _logger.LogInformation( "Found {VersionsCount} versions for package {PackageId} on upstream feed. Indexing...", versions.Count, id); // TODO: This will synchronously index packages one-by-one. This won't perform well // for packages with many versions. Instead, this should index a few packages and // let a background queue index the rest. // See: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1#queued-background-tasks foreach (var version in versions) { var packageUri = await _upstreamFeed.GetPackageContentUriAsync(id, version); await IndexFromSourceAsync(packageUri, cancellationToken); } _logger.LogInformation("Finished indexing {PackageId} from the upstream feed", id); }
private async Task IndexFromSourceAsync(string id, NuGetVersion version, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); _logger.LogInformation( "Attempting to mirror package {PackageId} {PackageVersion}...", id, version); try { var packageUri = await _upstreamFeed.GetPackageContentUriAsync(id, version); using (var stream = await _downloader.DownloadOrNullAsync(packageUri, cancellationToken)) { if (stream == null) { _logger.LogWarning( "Failed to download package {PackageId} {PackageVersion}", id, version); return; } _logger.LogInformation( "Downloaded package {PackageId} {PackageVersion}, indexing...", id, version); var result = await _indexer.IndexAsync(stream, cancellationToken); _logger.LogInformation( "Finished indexing package {PackageId} {PackageVersion} with result {Result}", packageUri, result); } } catch (Exception e) { _logger.LogError( e, "Failed to mirror package {PackageId} {PackageVersion}", id, version); } }