예제 #1
0
        /// <summary>
        /// Extracts a deploy anncouncement.
        /// </summary>
        /// <param name="announcement">The announcement that needs to be extracted.</param>
        /// <param name="token">Token of cancellation.</param>
        /// <inheritdoc />
        /// <exception cref="AggregateException">Throw when one or more fusions failed to extract.</exception>
        public void Extract(IDeployAnnouncement announcement, CancellationToken token)
        {
            EnsureArg.IsNotNull(announcement, nameof(announcement));

            var opts = new ParallelOptions
            {
                CancellationToken = token
            };

            var fusionIds = announcement.GetFusionIds();

            Parallel.ForEach(fusionIds, opts, (_, state) =>
            {
                try
                {
                    ExtractFusion(_, announcement);
                }
                catch (Exception ex)
                {
                    state.Stop();

                    throw new FusionException(FusionException.ExtractionFailure, _, ex);
                }
            });
        }
예제 #2
0
        private void ExtractFusion(string fusionId, IDeployAnnouncement announcement)
        {
            EnsureArg.IsNotNullOrEmpty(fusionId, nameof(fusionId));
            EnsureArg.IsNotNull(announcement, nameof(announcement));

            var fusionConfig = GetFusionConfig(fusionId);

            var packageVersions = announcement
                                  .GetPackageVersions(fusionConfig.Id)
                                  .Stale();

            packageVersionValidator
            .ConfirmAvailability(packageVersions);

            using (var packageStream = new MemoryStream())
            {
                var fusion = fusionFactory
                             .CreateNew(packageStream);

                try
                {
                    fusionBuilder.Build(fusionConfig, fusion, packageVersions);
                }
                finally
                {
                    (fusion as IDisposable)?.Dispose();
                }

                using (var packageStreamReadable = new MemoryStream(packageStream.ToArray()))
                {
                    fusionExtractor.Extract(fusionConfig, packageStreamReadable);
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Schedules an <see cref="IDeployAnnouncement"/>.
        /// </summary>
        /// <param name="announcement">The announcement that needs to be scheduled.</param>
        /// <param name="token">The token of cancellation.</param>
        /// <inheritdoc />
        public async Task ScheduleAsync(IDeployAnnouncement announcement, CancellationToken token)
        {
            EnsureArg.IsNotNull(announcement, nameof(announcement));

            var fusionIds = announcement
                            .GetFusionIds()
                            .OrderBy(_ => GetOrderId(_))
                            .Stale();

            if (!isFullCompleted &&
                announcement.IsDelta())
            {
                throw new ScheduleException(ScheduleException.FullAnnouncementRequired, "*");
            }

            await syncLock.WaitAsync();

            try
            {
                var activeProcesses = GetActiveProcesses(fusionIds);

                await TerminateMultipleAsync(activeProcesses, token); // drains and stops the services

                logService.Info("Terminated all active fusion(s).");

                fusionService.Extract(announcement, token); // extracts the new fusions

                logService.Info("Extracted all new fusion(s).");

                var newProcesses = SpawnMultiple(fusionIds, token).Stale(); // spawns the services

                logService.Info("Spawned all new fusion(s).");

                await WaitForAnnouncements(newProcesses, token); // wait for all port callbacks

                logService.Info("Received all announcements from the new fusion(s).");

                await StartupMultipleAsync(newProcesses, token); // calls all the startups + nurse statusses

                logService.Info("Started all new fusion(s) and checked their patient(s).");

                ResumeAll(token);

                logService.Info("Resumed all drainers, deployment completed.");

                if (!announcement.IsDelta())
                {
                    isFullCompleted = true;
                }
            }
            finally
            {
                syncLock.Release();
            }
        }
예제 #4
0
        /// <summary>
        /// Publishes the versions to the server.
        /// </summary>
        /// <param name="announcement">Announcement that needs to be published.</param>
        /// <param name="token">Token used to cancel the announcement.</param>
        /// <inheritDoc />
        public async Task PublishAsync(IDeployAnnouncement announcement, CancellationToken token)
        {
            EnsureArg.IsNotNull(announcement, nameof(announcement));

            var newPackageVersions = announcement
                                     .GetNewPackageVersions()
                                     .Stale();

            if (!newPackageVersions.Any())
            {
                return;
            }

            foreach (var version in newPackageVersions)
            {
                token.ThrowIfCancellationRequested();

                await PublishAsync(version);
            }
        }