public async Task LeaseConflictTests(string storageConnectionString, string siteName) { if (string.IsNullOrEmpty(storageConnectionString)) { return; } AppServiceSettings.StorageConnectionString = storageConnectionString; AppServiceSettings.SiteName = siteName; AppServiceSettings.WorkerName = "127.0.0.1"; try { var table = AppServiceWorkerTable.Instance; ILockHandle tableLock = null; try { tableLock = await table.AcquireLock(); var exception = await Assert.ThrowsAsync <InvalidOperationException>(async() => await table.AcquireLock()); Assert.Contains("Conflict", exception.Message); await tableLock.Release(); tableLock = null; } finally { if (tableLock != null) { await tableLock.Release(); } } Assert.Null(tableLock); } finally { ResetEnvironment(); } }
/// <summary> /// Releases a lock. /// </summary> /// <param name="handle">The handle.</param> /// <returns>If the lock was released by this manager.</returns> public async Task <bool> ReleaseAsync(ILockHandle handle) { if (_disposed == 1) { throw new ObjectDisposedException("The lock manager has been disposed"); } if (handle.Manager != this) { throw new InvalidOperationException("The handle does not belong this lock manager"); } // release the lock with the token. bool success = await _database.LockReleaseAsync($"tandem.{handle.ResourceURI.ToString()}", ((RedisLockHandle)handle).Token.ToString()).ConfigureAwait(false); lock (_handles) { try { _handles.Remove((RedisLockHandle)handle); } catch (Exception) { } } return(success); }
/// <summary> /// Releases a lock. /// </summary> /// <param name="handle">The handle.</param> /// <returns></returns> public Task <bool> ReleaseAsync(ILockHandle handle) { bool removed = false; // try and remove the handle from our lokc list lock (_handles) { if (_handles.Contains(handle)) { _handles.Remove((SlimLockHandle)handle); // we suceeded removed = true; } } // check if any locks waiting for this lock to be removed if (removed) { lock (_lockQueues) { while (true) { // get waiting list or create List <TaskCompletionSource <ILockHandle> > waitingList = null; // check if we did actually complete if (_lockQueues.TryGetValue(handle.ResourceURI.ToString(), out waitingList)) { // get the next lock to fulfill TaskCompletionSource <ILockHandle> waitingTask = waitingList[0]; waitingList.RemoveAt(0); // create our handle SlimLockHandle newHandle = new SlimLockHandle(this) { ResourceURI = handle.ResourceURI, Token = new LockToken(Guid.NewGuid(), null) }; // add to lock list _handles.Add(newHandle); // try and signal that the lock has been granted bool signaledLock = waitingTask.TrySetResult(newHandle); // remove if waiting list is empty if (waitingList.Count == 0) { _lockQueues.Remove(handle.ResourceURI.ToString()); } // if we signalled a lock or we're out of locks stop if (signaledLock || waitingList.Count == 0) { break; } } } } return(Task.FromResult(true)); } return(Task.FromResult(false)); }