Esempio n. 1
0
        public async Task PerformReplication()
        {
            try
            {
                Log.Logger.Verbose("Concurrent task limit used for replication: {limit}.", ConcurrentTasksLimit);
                var throttler = new SemaphoreSlim(ConcurrentTasksLimit);

                Log.Logger.Information("Fetching packages from providers...");
                var fetchTasks = new[]
                {
                    _sourceProvider.GetPackages(since: DateTime.MinValue),
                    _destinationProvider.GetPackages(since: DateTime.MinValue)
                };

                await Task.WhenAll(fetchTasks);

                Log.Logger.Information("Fetched packages from providers.");

                var sourcePackages      = fetchTasks[0].Result;
                var destinationPackages = fetchTasks[1].Result;

                var packagesToMirror = sourcePackages.Except(destinationPackages, PackageDefinition.FullComparer).ToList();

                Log.Logger.Information("# of packages on source: {numberOfPackages}", sourcePackages.Count);
                Log.Logger.Information("# of packages on destination: {numberOfPackages}", destinationPackages.Count);
                Log.Logger.Information("# of packages to replicate from source to destination: {numberOfPackages}", packagesToMirror.Count);

                // 1. Mirror packages from source that are not in destination
                var mirrorTasks = new List <Task>();
                foreach (var packageDefinition in packagesToMirror.OrderBy(p => p.PackageIdentifier).ThenBy(p => p.PackageVersion))
                {
                    mirrorTasks.Add(Task.Factory.StartNew(async() =>
                    {
                        try
                        {
                            await throttler.WaitAsync();

                            Log.Logger.Verbose(
                                "Replicating {packageType} package {packageIdentifier}@{packageVersion} from source to destination...",
                                packageDefinition.PackageType, packageDefinition.PackageIdentifier, packageDefinition.PackageVersion);

                            using (var packageStream = await StreamUtilities.MakeSeekable(
                                       await _sourceProvider.GetPackageStream(packageDefinition)))
                            {
                                await _destinationProvider.PushPackage(packageDefinition, packageStream);
                            }

                            Log.Logger.Information(
                                "Replicated {packageType} package {packageIdentifier}@{packageVersion} from source to destination.",
                                packageDefinition.PackageType, packageDefinition.PackageIdentifier,
                                packageDefinition.PackageVersion);
                        }
                        catch (HttpRequestException requestException)
                        {
                            if (requestException.Message.IndexOf("404", StringComparison.OrdinalIgnoreCase) >= 0)
                            {
                                Log.Logger.Error(
                                    "Replicating {packageType} package {packageIdentifier}@{packageVersion} failed: source returned 404 status code.",
                                    packageDefinition.PackageType, packageDefinition.PackageIdentifier, packageDefinition.PackageVersion);
                            }
                        }
                        finally
                        {
                            throttler.Release();
                        }
                    }).Unwrap());
                }

                await Task.WhenAll(mirrorTasks);
            }
            catch (Exception ex)
            {
                Log.Logger.Error($"Application: NuGet Sync. Hostname: {System.Environment.MachineName} - An Error Occurred: {ex.Message}");
            }
        }