/// <summary> /// Gets a collections of module updates that have already been applied /// to the system. /// </summary> private async Task <ICollection <ModuleVersion> > GetUpdateVersionHistoryAsync() { var query = @" if (exists (select * from information_schema.tables where table_schema = 'Cofoundry' and table_name = 'ModuleUpdate')) begin select Module, MAX([Version]) as Version from Cofoundry.ModuleUpdate group by Module order by Module end"; var moduleVersions = await _db.ReadAsync(query, r => { var moduleVersion = new ModuleVersion(); moduleVersion.Module = (string)r["Module"]; moduleVersion.Version = (int)r["Version"]; return(moduleVersion); }); return(moduleVersions); }
public async Task LockAsync(Guid lockingId) { await EnsureDistributedLockInfrastructureExistsAsync(); var query = @" declare @DateNow datetime2(7) = GetUtcDate() update Cofoundry.DistributedLock set LockingId = @LockingId, LockDate = @DateNow, ExpiryDate = dateadd(second, @TimeoutInSeconds, @DateNow) where DistributedLockId = @DistributedLockId and (LockingId is null or ExpiryDate < @DateNow) select DistributedLockId, LockingId, LockDate, ExpiryDate from Cofoundry.DistributedLock where DistributedLockId = @DistributedLockId "; var distributedLock = (await _db.ReadAsync(query, MapDistributedLock, new SqlParameter("DistributedLockId", DISTRIBUTED_LOCK_ID), new SqlParameter("LockingId", lockingId), new SqlParameter("TimeoutInSeconds", _autoUpdateSettings.ProcessLockTimeoutInSeconds) )) .SingleOrDefault(); if (distributedLock == null) { throw new Exception($"Distributed lock record missing for the auto update process. DistributedLockId: {DISTRIBUTED_LOCK_ID}"); } if (distributedLock.LockingId != lockingId) { throw new AutoUpdateProcessLockedException(distributedLock); } }
/// <summary> /// Creates a lock for the specified definition using a unique /// lock id that represents the running process. You can /// query the returned DistributedLock instance to determine if /// the lock was successful. /// </summary> /// <typeparam name="TDefinition"> /// The definition type that conmtains the locking parameters that /// represent the process to be run. /// </typeparam> /// <returns> /// Returns the current state of the lock for the specified /// definition. If the lock could not be made then the state will /// contain information about the existing lock, if the lock was /// successful then the new lock will be returned. You can /// query the returned object to determine if the lock was successful. /// </returns> public async Task <DistributedLock> LockAsync <TDefinition>() where TDefinition : IDistributedLockDefinition { var distributedLockDefinition = _distributedLockDefinitionRepository.Get <TDefinition>(); EntityNotFoundException.ThrowIfNull(distributedLockDefinition, typeof(TDefinition)); var lockingId = Guid.NewGuid(); var query = @" declare @DateNow datetime2(7) = GetUtcDate(); with data as (select @DistributedLockId as DistributedLockId, @DistributedLockName as [Name]) merge Cofoundry.DistributedLock t using data s on s.DistributedLockId = t.DistributedLockId when not matched by target then insert (DistributedLockId, [Name]) values (s.DistributedLockId, s.[Name]); update Cofoundry.DistributedLock set LockingId = @LockingId, LockDate = @DateNow, ExpiryDate = dateadd(second, @TimeoutInSeconds, @DateNow) where DistributedLockId = @DistributedLockId and (LockingId is null or ExpiryDate < @DateNow) select DistributedLockId, LockingId, LockDate, ExpiryDate from Cofoundry.DistributedLock where DistributedLockId = @DistributedLockId "; var distributedLock = (await _db.ReadAsync(query, MapDistributedLock, new SqlParameter("DistributedLockId", distributedLockDefinition.DistributedLockId), new SqlParameter("DistributedLockName", distributedLockDefinition.Name), new SqlParameter("LockingId", lockingId), new SqlParameter("TimeoutInSeconds", distributedLockDefinition.Timeout.TotalSeconds) )) .SingleOrDefault(); if (distributedLock == null) { throw new Exception($"Unknown error creating a distributed lock with a DistributedLockId of '{distributedLockDefinition.DistributedLockId}'"); } distributedLock.RequestedLockingId = lockingId; return(distributedLock); }