Ejemplo n.º 1
0
        private async Task RunUpdates(ICollection <UpdatePackage> packages, CancellationToken?cancellationToken)
        {
            // Lock the process to prevent concurrent updates
            var distributedLock = await _autoUpdateDistributedLockManager.LockAsync();

            try
            {
                foreach (var package in packages)
                {
                    if (IsCancelled(cancellationToken))
                    {
                        break;
                    }

                    await ExecutePackage(package, cancellationToken);
                }
            }
            catch (Exception updateProcessException)
            {
                // Try and close the lock before we throw the exception
                try
                {
                    await _autoUpdateDistributedLockManager.UnlockAsync(distributedLock);
                }
                catch (Exception unlockException)
                {
                    _logger.LogError(unlockException, unlockException.Message);
                }

                throw;
            }

            await _autoUpdateDistributedLockManager.UnlockAsync(distributedLock);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Updates an application and referenced modules by scanning for implementations
        /// of IUpdatePackageFactory and executing any packages found.
        /// </summary>
        /// <remarks>
        /// Async because sometimes UpdateCommands need to be async to save having to create
        /// sync versions of methods that would not normally require them. E.g. when calling into
        /// shared command handlers. I don't really think there's much benefit in making any other
        /// part async because nothing else useful should be happening while the db update is going on anyway.
        /// </remarks>
        public async Task UpdateAsync()
        {
            var previouslyAppliedVersions = await GetUpdateVersionHistoryAsync();

            var filteredPackages = _updatePackageFactories
                                   .SelectMany(f => f.Create(previouslyAppliedVersions))
                                   .ToList();

            var packages = _updatePackageOrderer.Order(filteredPackages);

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

            if (await IsLockedAsync())
            {
                throw new DatabaseLockedException();
            }

            // Lock the process to prevent concurrent updates
            var distributedLock = await _autoUpdateDistributedLockManager.LockAsync();

            try
            {
                foreach (var package in packages)
                {
                    await ExecutePackage(package);
                }
            }
            finally
            {
                await _autoUpdateDistributedLockManager.UnlockAsync(distributedLock);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Updates an application and referenced modules by scanning for implementations
        /// of IUpdatePackageFactory and executing any packages found.
        /// </summary>
        public async Task UpdateAsync(CancellationToken?cancellationToken = null)
        {
            var previouslyAppliedVersions = await GetUpdateVersionHistoryAsync();

            var filteredPackages = _updatePackageFactories
                                   .SelectMany(f => f.Create(previouslyAppliedVersions))
                                   .ToList();

            var packages = _updatePackageOrderer.Order(filteredPackages);

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

            var isLocked = await IsLockedAsync();

            if (isLocked && !packages.Any(p => p.ContainsVersionUpdates()))
            {
                // if locked ignore always-update commands and only throw if there
                // are required version updates.
                return;
            }
            else if (isLocked)
            {
                throw new DatabaseLockedException();
            }

            if (IsCancelled(cancellationToken))
            {
                return;
            }

            // Lock the process to prevent concurrent updates
            var distributedLock = await _autoUpdateDistributedLockManager.LockAsync();

            try
            {
                foreach (var package in packages)
                {
                    if (IsCancelled(cancellationToken))
                    {
                        break;
                    }

                    await ExecutePackage(package, cancellationToken);
                }
            }
            finally
            {
                await _autoUpdateDistributedLockManager.UnlockAsync(distributedLock);
            }
        }