private ScarletLock() { var container = TinyIoCContainer.Current; container .Register((kernel, overloads) => DistributedLockFactory <Guid> .Create(Guid.NewGuid)); container .Register((kernel, overloads) => DistributedLockManagerFactory.Create()); }
public async Task <IDistributedLock <TIdentity> > AcquireDistributedLockAsync(string resource, TimeSpan ttl) { var drift = TimeSpan.FromMilliseconds(Convert.ToInt32((ttl.TotalMilliseconds * 0.01) + 2)); var preliminaryLock = DistributedLockFactory.GetPreliminaryLock(resource); return(await RetryPolicy .ExecuteAsync(async() => { var startTime = DateTime.Now; var locksAcquired = 0; var temporaryLocks = new List <IConnection>(); foreach (var connection in Connections) { if (await AttemptLockOnInstanceAsync(connection, preliminaryLock, ttl)) { temporaryLocks.Add(connection); locksAcquired++; } } var validityTime = ttl - (DateTime.Now - startTime) - drift; if (locksAcquired >= QuorumCount && validityTime.TotalMilliseconds > 0) { return DistributedLockFactory.EstablishLock(this, preliminaryLock, DateTime.Now + validityTime); } //Locking was not successful, release our previous locks. foreach (var connection in temporaryLocks) { await UnlockOnInstanceAsync(connection, preliminaryLock); } //We need to wait, throw so retry policy can execute. throw new BlockedException(); })); }