public async Task AddOrUpdateAsync(
            CatalogPageEntry page,
            IReadOnlyList <CatalogEntry> leaves,
            IReadOnlyDictionary <string, long> identityToPackageKey)
        {
            _logger.LogInformation("Adding or updating catalog page {PageUri}.", page.Uri.OriginalString);
            using (var context = new EntityContext())
            {
                var pageUrl  = page.Uri.OriginalString;
                var existing = await context
                               .CatalogPages
                               .Include(x => x.CatalogCommits)
                               .ThenInclude(x => x.CatalogLeaves)
                               .Where(x => x.Url == pageUrl)
                               .FirstOrDefaultAsync();

                var latest = await InitializeAsync(pageUrl, leaves, identityToPackageKey);

                Merge(context, existing, latest);

                var commitStopwatch = Stopwatch.StartNew();
                var changes         = await context.SaveChangesAsync();

                _logger.LogInformation("Committed {Changes} changes. {ElapsedMilliseconds}ms", changes, commitStopwatch.ElapsedMilliseconds);
            }
        }
        public async Task ProcessAsync(CatalogPageEntry page, IReadOnlyList <CatalogEntry> leaves)
        {
            var latestLeaves = leaves
                               .GroupBy(x => new PackageIdentity(x.Id, x.Version.ToNormalizedString()))
                               .Select(x => x
                                       .OrderByDescending(y => y.CommitTimeStamp)
                                       .First())
                               .ToList();

            var identityToPackageKey = await _packageService.AddOrUpdatePackagesAsync(latestLeaves);

            await _catalogService.AddOrUpdateAsync(page, leaves, identityToPackageKey);

            await _packageService.SetDeletedPackagesAsUnlistedInV2Async(latestLeaves.Where(x => x.IsDelete));
        }
        public async Task ProcessAsync(CatalogPageEntry page, IReadOnlyList <CatalogEntry> leaves)
        {
            var packageIdentities = leaves
                                    .Select(x => new PackageIdentity(x.Id, x.Version.ToNormalizedString()))
                                    .Distinct()
                                    .ToList();

            var work = new ConcurrentBag <PackageIdentity>(packageIdentities);

            var tasks = Enumerable
                        .Range(0, 32)
                        .Select(i => DownloadNuspecAsync(work))
                        .ToList();

            await Task.WhenAll(tasks);
        }
 public Work(CatalogPageEntry page, IReadOnlyList <CatalogEntry> leaves)
 {
     Page   = page;
     Leaves = leaves;
 }