public void Lock_OneShot() { var client = new ConsulClient(); const string keyName = "test/lock/oneshot"; var lockOptions = new LockOptions(keyName) { LockTryOnce = true }; Assert.Equal(Lock.DefaultLockWaitTime, lockOptions.LockWaitTime); lockOptions.LockWaitTime = TimeSpan.FromMilliseconds(1000); var lockKey = client.CreateLock(lockOptions); lockKey.Acquire(CancellationToken.None); var contender = client.CreateLock(new LockOptions(keyName) { LockTryOnce = true, LockWaitTime = TimeSpan.FromMilliseconds(1000) }); var stopwatch = Stopwatch.StartNew(); Exception didExcept = null; Task.WaitAny( Task.Run(() => { // Needed because async asserts don't work in sync methods! try { contender.Acquire(); } catch (Exception e) { didExcept = e; } }), Task.Delay((int)(2 * lockOptions.LockWaitTime.TotalMilliseconds)).ContinueWith((t) => Assert.True(false, "Took too long")) ); Assert.False(stopwatch.ElapsedMilliseconds < lockOptions.LockWaitTime.TotalMilliseconds); Assert.False(contender.IsHeld, "Contender should have failed to acquire"); Assert.IsType <LockMaxAttemptsReachedException>(didExcept); lockKey.Release(); contender.Acquire(); Assert.True(contender.IsHeld); contender.Release(); contender.Destroy(); }
public async Task Lock_AcquireWaitRelease() { var client = new ConsulClient(); const string keyName = "test/lock/acquirewaitrelease"; var lockOptions = new LockOptions(keyName) { SessionName = "test_locksession", SessionTTL = TimeSpan.FromSeconds(10) }; var l = client.CreateLock(lockOptions); await l.Acquire(CancellationToken.None); Assert.True(l.IsHeld); // Wait for multiple renewal cycles to ensure the lock session stays renewed. Task.Delay(TimeSpan.FromSeconds(60)).Wait(); Assert.True(l.IsHeld); await l.Release(); Assert.False(l.IsHeld); await l.Destroy(); }
public async Task Cancelling_A_Token_When_Acquiring_A_Lock_Should_Throw_TaskCanceledException() { var keyName = Path.GetRandomFileName(); var masterClient = new ConsulClient(c => { c.Token = TestHelper.MasterToken; c.Address = TestHelper.HttpUri; }); var distributedLock2 = masterClient.CreateLock(new LockOptions(keyName) { SessionTTL = TimeSpan.FromSeconds(DefaultSessionTTLSeconds), LockWaitTime = TimeSpan.FromSeconds(LockWaitTimeSeconds) }); var distributedLock = _client.CreateLock(new LockOptions(keyName) { SessionTTL = TimeSpan.FromSeconds(DefaultSessionTTLSeconds), LockWaitTime = TimeSpan.FromSeconds(LockWaitTimeSeconds) }); await distributedLock2.Acquire(); // Become "Master" with another instance first var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); await Assert.ThrowsAsync <TaskCanceledException>(async() => await distributedLock.Acquire(cts.Token)); await distributedLock2.Release(); await distributedLock2.Destroy(); masterClient.Dispose(); }
public void Lock_SemaphoreConflict() { var client = new ConsulClient(); const string keyName = "test/lock/semaphoreconflict"; var semaphore = client.Semaphore(keyName, 2); semaphore.Acquire(CancellationToken.None); Assert.True(semaphore.IsHeld); var lockKey = client.CreateLock(keyName + "/.lock"); try { lockKey.Acquire(CancellationToken.None); } catch (LockConflictException ex) { Assert.IsType <LockConflictException>(ex); } try { lockKey.Destroy(); } catch (LockConflictException ex) { Assert.IsType <LockConflictException>(ex); } semaphore.Release(); semaphore.Destroy(); }
public async Task Cancelling_A_Token_When_Acquiring_A_Lock_Respects_The_Token() { var keyName = Path.GetRandomFileName(); var masterInstanceClient = new ConsulClient(c => { c.Token = TestHelper.MasterToken; c.Address = TestHelper.HttpUri; }); // Arrange var distributedLock2 = masterInstanceClient.CreateLock(new LockOptions(keyName) { SessionTTL = TimeSpan.FromSeconds(DefaultSessionTTLSeconds), LockWaitTime = TimeSpan.FromSeconds(LockWaitTimeSeconds) }); var distributedLock = _client.CreateLock(new LockOptions(keyName) { SessionTTL = TimeSpan.FromSeconds(DefaultSessionTTLSeconds), LockWaitTime = TimeSpan.FromSeconds(LockWaitTimeSeconds) }); var cancellationOperationTimer = new Stopwatch(); // Act await distributedLock2.Acquire(); // Become "Master" with another instance first cancellationOperationTimer.Start(); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); try { await distributedLock.Acquire(cts.Token); } catch (Exception) { } cancellationOperationTimer.Stop(); // Assert var stopTimeMs = cancellationOperationTimer.ElapsedMilliseconds; var lockWaitTimeMs = TimeSpan.FromSeconds(LockWaitTimeSeconds).TotalMilliseconds; Assert.True(stopTimeMs < lockWaitTimeMs); // cleanup await distributedLock2.Release(); if (distributedLock.IsHeld) { await distributedLock2.Release(); } await distributedLock2.Destroy(); masterInstanceClient.Dispose(); }
public void Lock_OneShot() { var client = new ConsulClient(); const string keyName = "test/lock/oneshot"; var lockOptions = new LockOptions(keyName) { LockTryOnce = true }; Assert.Equal(Lock.DefaultLockWaitTime, lockOptions.LockWaitTime); lockOptions.LockWaitTime = TimeSpan.FromMilliseconds(250); var lockKey = client.CreateLock(lockOptions); lockKey.Acquire(CancellationToken.None); var contender = client.CreateLock(new LockOptions(keyName) { LockTryOnce = true, LockWaitTime = TimeSpan.FromMilliseconds(250) }); Task.WaitAny(Task.Run(() => { Assert.Throws <LockMaxAttemptsReachedException>(() => contender.Acquire() ); }), Task.Delay(2 * lockOptions.LockWaitTime.Milliseconds).ContinueWith((t) => Assert.True(false, "Took too long")) ); lockKey.Release(); contender.Acquire(); contender.Release(); contender.Destroy(); }
public async Task <ILock> LockAsync(string ck, int ttl = 5000, int retry = 2, int retryDelay = 1000) { var id = Guid.NewGuid(); var o = new LockOptions(ck) { Value = id.ToByteArray(), SessionName = id.ToString("n"), SessionTTL = TimeSpan.FromMilliseconds(ttl), LockRetryTime = TimeSpan.FromMilliseconds(retryDelay), LockWaitTime = TimeSpan.FromMilliseconds(retry * retryDelay), }; var lck = _client.CreateLock(o); var ct = await lck.Acquire(CancellationToken.None).ConfigureAwait(false); return(new Lock(_client, o, lck, ct)); }
public async Task Lock_Contend_LockDelay() { var client = new ConsulClient(); const string keyName = "test/lock/contendlockdelay"; const int contenderPool = 3; var acquired = new System.Collections.Concurrent.ConcurrentDictionary <int, bool>(); using (var cts = new CancellationTokenSource()) { cts.CancelAfter((contenderPool + 1) * (int)Lock.DefaultLockWaitTime.TotalMilliseconds); var tasks = new List <Task>(); for (var i = 0; i < contenderPool; i++) { var v = i; tasks.Add(Task.Run(async() => { var lockKey = (Lock)client.CreateLock(keyName); await lockKey.Acquire(CancellationToken.None); if (lockKey.IsHeld) { Assert.True(acquired.TryAdd(v, lockKey.IsHeld)); await client.Session.Destroy(lockKey.LockSession); } })); } await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(Timeout.Infinite, cts.Token)); } for (var i = 0; i < contenderPool; i++) { bool didContend = false; if (acquired.TryGetValue(i, out didContend)) { Assert.True(didContend); } else { Assert.True(false, "Contender " + i.ToString() + " did not acquire the lock"); } } }
public async Task Lock_ContendFast() { var client = new ConsulClient(); const string keyName = "test/lock/contendfast"; const int contenderPool = 10; var acquired = new System.Collections.Concurrent.ConcurrentDictionary <int, bool>(); using (var cts = new CancellationTokenSource()) { cts.CancelAfter(contenderPool * (int)Lock.DefaultLockWaitTime.TotalMilliseconds); var tasks = new List <Task>(); for (var i = 0; i < contenderPool; i++) { var v = i; tasks.Add(Task.Run(async() => { var lockKey = client.CreateLock(keyName); await lockKey.Acquire(CancellationToken.None); Assert.True(acquired.TryAdd(v, lockKey.IsHeld)); if (lockKey.IsHeld) { await lockKey.Release(); } })); } await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(Timeout.Infinite, cts.Token)); } for (var i = 0; i < contenderPool; i++) { if (acquired[i]) { Assert.True(acquired[i]); } else { Assert.True(false, "Contender " + i.ToString() + " did not acquire the lock"); } } }
public void Lock_AcquireRelease() { var client = new ConsulClient(); const string keyName = "test/lock/acquirerelease"; var lockKey = client.CreateLock(keyName); try { lockKey.Release(); } catch (LockNotHeldException ex) { Assert.IsType<LockNotHeldException>(ex); } lockKey.Acquire(CancellationToken.None); try { lockKey.Acquire(CancellationToken.None); } catch (LockHeldException ex) { Assert.IsType<LockHeldException>(ex); } Assert.True(lockKey.IsHeld); lockKey.Release(); try { lockKey.Release(); } catch (LockNotHeldException ex) { Assert.IsType<LockNotHeldException>(ex); } Assert.False(lockKey.IsHeld); }
public async Task Lock_AcquireRelease() { var client = new ConsulClient(); const string keyName = "test/lock/acquirerelease"; var lockKey = client.CreateLock(keyName); try { await lockKey.Release(); } catch (LockNotHeldException ex) { Assert.IsType <LockNotHeldException>(ex); } await lockKey.Acquire(CancellationToken.None); try { await lockKey.Acquire(CancellationToken.None); } catch (LockHeldException ex) { Assert.IsType <LockHeldException>(ex); } Assert.True(lockKey.IsHeld); await lockKey.Release(); try { await lockKey.Release(); } catch (LockNotHeldException ex) { Assert.IsType <LockNotHeldException>(ex); } Assert.False(lockKey.IsHeld); }
public async Task Lock_ForceInvalidate() { var client = new ConsulClient(); const string keyName = "test/lock/forceinvalidate"; var lockKey = (Lock)client.CreateLock(keyName); try { await lockKey.Acquire(CancellationToken.None); Assert.True(lockKey.IsHeld); var checker = Task.Run(async() => { while (lockKey.IsHeld) { await Task.Delay(10); } Assert.False(lockKey.IsHeld); }); await Task.Run(() => { client.Session.Destroy(lockKey.LockSession); }); Task.WaitAny(new[] { checker }, 1000); } finally { try { await lockKey.Release(); await lockKey.Destroy(); } catch (LockNotHeldException ex) { Assert.IsType <LockNotHeldException>(ex); } } }
public async Task Lock_DeleteKey() { var client = new ConsulClient(); const string keyName = "test/lock/deletekey"; var lockKey = (Lock)client.CreateLock(keyName); try { await lockKey.Acquire(CancellationToken.None); Assert.True(lockKey.IsHeld); var checker = Task.Run(() => { while (lockKey.IsHeld) { Thread.Sleep(10); } Assert.False(lockKey.IsHeld); }); Task.WaitAny(new[] { checker }, 1000); await client.KV.Delete(lockKey.Opts.Key); } finally { try { await lockKey.Release(); await lockKey.Destroy(); } catch (LockNotHeldException ex) { Assert.IsType <LockNotHeldException>(ex); } } }
public void Lock_MultithreadedRelease() { const int numTasks = 100000; using (var client = new ConsulClient()) { const string keyName = "test/lock/acquirerelease"; var lockKey = client.CreateLock(keyName); Task[] tasks = new Task[numTasks]; for (int i = 0; i < numTasks; i++) { tasks[i] = lockKey.Acquire(CancellationToken.None); } try { Task.WaitAll(tasks); } catch (AggregateException e) { Assert.Equal(numTasks - 1, e.InnerExceptions.Count); } Assert.True(lockKey.IsHeld); for (int i = 0; i < numTasks; i++) { tasks[i] = lockKey.Release(CancellationToken.None); } try { Task.WaitAll(tasks); } catch (AggregateException e) { Assert.Equal(numTasks - 1, e.InnerExceptions.Count); } } }
public void Lock_Contend_LockDelay() { var client = new ConsulClient(); const string keyName = "test/lock/contendlockdelay"; const int contenderPool = 3; var acquired = new System.Collections.Concurrent.ConcurrentDictionary <int, bool>(); using (var cts = new CancellationTokenSource()) { cts.CancelAfter((contenderPool + 1) * (int)Lock.DefaultLockWaitTime.TotalMilliseconds); Parallel.For(0, contenderPool, new ParallelOptions { MaxDegreeOfParallelism = contenderPool, CancellationToken = cts.Token }, (v) => { var lockKey = (Lock)client.CreateLock(keyName); lockKey.Acquire(CancellationToken.None); if (lockKey.IsHeld) { Assert.True(acquired.TryAdd(v, lockKey.IsHeld)); client.Session.Destroy(lockKey.LockSession); } }); } for (var i = 0; i < contenderPool; i++) { bool didContend = false; if (acquired.TryGetValue(i, out didContend)) { Assert.True(didContend); } else { Assert.True(false, "Contender " + i.ToString() + " did not acquire the lock"); } } }
public void Lock_ContendWait() { var client = new ConsulClient(); const string keyName = "test/lock/contendwait"; const int contenderPool = 3; var acquired = new System.Collections.Concurrent.ConcurrentDictionary <int, bool>(); using (var cts = new CancellationTokenSource()) { cts.CancelAfter(contenderPool * (int)Lock.DefaultLockWaitTime.TotalMilliseconds); Parallel.For(0, contenderPool, new ParallelOptions { MaxDegreeOfParallelism = contenderPool, CancellationToken = cts.Token }, (v) => { var lockKey = client.CreateLock(keyName); lockKey.Acquire(CancellationToken.None); Assert.True(acquired.TryAdd(v, lockKey.IsHeld)); if (lockKey.IsHeld) { Task.Delay(1000).Wait(); lockKey.Release(); } }); } for (var i = 0; i < contenderPool; i++) { if (acquired[i]) { Assert.True(acquired[i]); } else { Assert.True(false, "Contender " + i.ToString() + " did not acquire the lock"); } } }
public async Task Semaphore_Conflict() { const string keyName = "test/semaphore/conflict"; var semaphoreLock = _client.CreateLock(keyName + "/.lock"); await semaphoreLock.Acquire(CancellationToken.None); Assert.True(semaphoreLock.IsHeld); var semaphore = _client.Semaphore(keyName, 2); await Assert.ThrowsAsync <SemaphoreConflictException>(async() => await semaphore.Acquire(CancellationToken.None)); await Assert.ThrowsAsync <SemaphoreConflictException>(async() => await semaphore.Destroy()); await semaphoreLock.Release(); Assert.False(semaphoreLock.IsHeld); await semaphoreLock.Destroy(); }
private Task StartLeadershipTask(string resourceGroup, Guid clientId, CancellationToken token, BlockingCollection <ClientEvent> clientEvents) { return(Task.Run(async() => { using (var client = new ConsulClient(SetConfig)) { var key = $"rebalanser/resourcegroups/{resourceGroup}"; var session = client.CreateLock(key); while (!token.IsCancellationRequested) { var rgDetails = await GetResourceGroupAsync(client, resourceGroup); await session.Acquire(); if (session.IsHeld) { PostLeaderEvent(resourceGroup, session, clientEvents); while (!token.IsCancellationRequested) { await WaitFor(TimeSpan.FromSeconds(1), token); if (!session.IsHeld) { PostFollowerEvent(resourceGroup, clientEvents); break; } } } else { PostFollowerEvent(resourceGroup, clientEvents); await WaitFor(TimeSpan.FromSeconds(rgDetails.LeaderPollingInterval), token); } } } })); }
public async Task Semaphore_Conflict() { var client = new ConsulClient(); const string keyName = "test/semaphore/conflict"; var semaphoreLock = client.CreateLock(keyName + "/.lock"); await semaphoreLock.Acquire(CancellationToken.None); Assert.True(semaphoreLock.IsHeld); var semaphore = client.Semaphore(keyName, 2); try { await semaphore.Acquire(CancellationToken.None); } catch (SemaphoreConflictException ex) { Assert.IsType <SemaphoreConflictException>(ex); } try { await semaphore.Destroy(); } catch (SemaphoreConflictException ex) { Assert.IsType <SemaphoreConflictException>(ex); } await semaphoreLock.Release(); Assert.False(semaphoreLock.IsHeld); await semaphoreLock.Destroy(); }
public void Lock_DeleteKey() { var client = new ConsulClient(); const string keyName = "test/lock/deletekey"; var lockKey = (Lock)client.CreateLock(keyName); try { lockKey.Acquire(CancellationToken.None); Assert.True(lockKey.IsHeld); var checker = Task.Run(() => { while (lockKey.IsHeld) { Thread.Sleep(10); } Assert.False(lockKey.IsHeld); }); Task.WaitAny(new[] { checker }, 1000); client.KV.Delete(lockKey.Opts.Key); } finally { try { lockKey.Release(); lockKey.Destroy(); } catch (LockNotHeldException ex) { Assert.IsType<LockNotHeldException>(ex); } } }
public async Task Lock_ReclaimLock() { var client = new ConsulClient(); const string keyName = "test/lock/reclaim"; var sessionRequest = await client.Session.Create(); var sessionId = sessionRequest.Response; try { var lock1 = client.CreateLock(new LockOptions(keyName) { Session = sessionId }); var lock2 = client.CreateLock(new LockOptions(keyName) { Session = sessionId }); try { lock1.Acquire(CancellationToken.None); Assert.True(lock1.IsHeld); if (lock1.IsHeld) { Task.WaitAny(new[] { Task.Run(() => { lock2.Acquire(CancellationToken.None); Assert.True(lock2.IsHeld); }) }, 1000); } } finally { lock1.Release(); } var lockCheck = new[] { Task.Run(() => { while (lock1.IsHeld) { Thread.Sleep(10); } }), Task.Run(() => { while (lock2.IsHeld) { Thread.Sleep(10); } }) }; Task.WaitAll(lockCheck, 1000); Assert.False(lock1.IsHeld); Assert.False(lock2.IsHeld); } finally { Assert.True((await client.Session.Destroy(sessionId)).Response); } }
public void Semaphore_Conflict() { var client = new ConsulClient(); const string keyName = "test/semaphore/conflict"; var semaphoreLock = client.CreateLock(keyName + "/.lock"); semaphoreLock.Acquire(CancellationToken.None); Assert.True(semaphoreLock.IsHeld); var semaphore = client.Semaphore(keyName, 2); try { semaphore.Acquire(CancellationToken.None); } catch (SemaphoreConflictException ex) { Assert.IsType<SemaphoreConflictException>(ex); } try { semaphore.Destroy(); } catch (SemaphoreConflictException ex) { Assert.IsType<SemaphoreConflictException>(ex); } semaphoreLock.Release(); Assert.False(semaphoreLock.IsHeld); semaphoreLock.Destroy(); }
public void Lock_ContendFast() { var client = new ConsulClient(); const string keyName = "test/lock/contend"; const int contenderPool = 10; var acquired = new System.Collections.Concurrent.ConcurrentDictionary<int, bool>(); using (var cts = new CancellationTokenSource()) { cts.CancelAfter(contenderPool * (int)Lock.DefaultLockWaitTime.TotalMilliseconds); Parallel.For(0, contenderPool, new ParallelOptions { MaxDegreeOfParallelism = contenderPool, CancellationToken = cts.Token }, (v) => { var lockKey = client.CreateLock(keyName); lockKey.Acquire(CancellationToken.None); Assert.True(acquired.TryAdd(v, lockKey.IsHeld)); if (lockKey.IsHeld) { lockKey.Release(); } }); } for (var i = 0; i < contenderPool; i++) { if (acquired[i]) { Assert.True(acquired[i]); } else { Assert.True(false, "Contender " + i.ToString() + " did not acquire the lock"); } } }
public void Lock_AcquireWaitRelease() { var client = new ConsulClient(); const string keyName = "test/lock/acquirewaitrelease"; var lockOptions = new LockOptions(keyName) { SessionName = "test_locksession", SessionTTL = TimeSpan.FromSeconds(10) }; var l = client.CreateLock(lockOptions); l.Acquire(CancellationToken.None); Assert.True(l.IsHeld); // Wait for multiple renewal cycles to ensure the lock session stays renewed. Task.Delay(TimeSpan.FromSeconds(60)).Wait(); Assert.True(l.IsHeld); l.Release(); Assert.False(l.IsHeld); l.Destroy(); }
public void Lock_Contend_LockDelay() { var client = new ConsulClient(); const string keyName = "test/lock/contendlockdelay"; const int contenderPool = 3; var acquired = new System.Collections.Concurrent.ConcurrentDictionary<int, bool>(); using (var cts = new CancellationTokenSource()) { cts.CancelAfter((contenderPool + 1) * (int)Lock.DefaultLockWaitTime.TotalMilliseconds); Parallel.For(0, contenderPool, new ParallelOptions { MaxDegreeOfParallelism = contenderPool, CancellationToken = cts.Token }, (v) => { var lockKey = (Lock)client.CreateLock(keyName); lockKey.Acquire(CancellationToken.None); if (lockKey.IsHeld) { Assert.True(acquired.TryAdd(v, lockKey.IsHeld)); client.Session.Destroy(lockKey.LockSession); } }); } for (var i = 0; i < contenderPool; i++) { bool didContend = false; if (acquired.TryGetValue(i, out didContend)) { Assert.True(didContend); } else { Assert.True(false, "Contender " + i.ToString() + " did not acquire the lock"); } } }
public async Task Lock_ReclaimLock() { var client = new ConsulClient(); const string keyName = "test/lock/reclaim"; var sessionRequest = await client.Session.Create(); var sessionId = sessionRequest.Response; try { var lock1 = client.CreateLock(new LockOptions(keyName) { Session = sessionId }); var lock2 = client.CreateLock(new LockOptions(keyName) { Session = sessionId }); try { await lock1.Acquire(CancellationToken.None); Assert.True(lock1.IsHeld); if (lock1.IsHeld) { Assert.NotEqual(WaitHandle.WaitTimeout, Task.WaitAny(new[] { Task.Run(() => { lock2.Acquire(CancellationToken.None); Assert.True(lock2.IsHeld); }) }, 1000)); } } finally { await lock1.Release(); } var lockCheck = new[] { Task.Run(() => { while (lock1.IsHeld) { } }), Task.Run(() => { while (lock2.IsHeld) { } }) }; Assert.True(Task.WaitAll(lockCheck, 1000)); Assert.False(lock1.IsHeld, "Lock 1 still held"); Assert.False(lock2.IsHeld, "Lock 2 still held"); } finally { Assert.True((await client.Session.Destroy(sessionId)).Response, "Failed to destroy session"); } }
public void Lock_Destroy() { var client = new ConsulClient(); const string keyName = "test/lock/contendlockdelay"; var lockKey = client.CreateLock(keyName); try { lockKey.Acquire(CancellationToken.None); Assert.True(lockKey.IsHeld); try { lockKey.Destroy(); Assert.True(false); } catch (LockHeldException ex) { Assert.IsType<LockHeldException>(ex); } lockKey.Release(); Assert.False(lockKey.IsHeld); var lockKey2 = client.CreateLock(keyName); lockKey2.Acquire(CancellationToken.None); Assert.True(lockKey2.IsHeld); try { lockKey.Destroy(); Assert.True(false); } catch (LockInUseException ex) { Assert.IsType<LockInUseException>(ex); } lockKey2.Release(); Assert.False(lockKey2.IsHeld); lockKey.Destroy(); lockKey2.Destroy(); } finally { try { lockKey.Release(); } catch (LockNotHeldException ex) { Assert.IsType<LockNotHeldException>(ex); } } }
public async Task Lock_Destroy() { var client = new ConsulClient(); const string keyName = "test/lock/destroy"; var lockKey = client.CreateLock(keyName); try { await lockKey.Acquire(CancellationToken.None); Assert.True(lockKey.IsHeld); try { await lockKey.Destroy(); Assert.True(false); } catch (LockHeldException ex) { Assert.IsType <LockHeldException>(ex); } await lockKey.Release(); Assert.False(lockKey.IsHeld); var lockKey2 = client.CreateLock(keyName); await lockKey2.Acquire(CancellationToken.None); Assert.True(lockKey2.IsHeld); try { await lockKey.Destroy(); Assert.True(false); } catch (LockInUseException ex) { Assert.IsType <LockInUseException>(ex); } await lockKey2.Release(); Assert.False(lockKey2.IsHeld); await lockKey.Destroy(); await lockKey2.Destroy(); } finally { try { await lockKey.Release(); } catch (LockNotHeldException ex) { Assert.IsType <LockNotHeldException>(ex); } } }
public async Task Lock_AcquireRelease() { const string keyName = "test/lock/acquirerelease"; var lockKey = _client.CreateLock(keyName); await Assert.ThrowsAsync <LockNotHeldException>(async() => await lockKey.Release()); await lockKey.Acquire(CancellationToken.None); await Assert.ThrowsAsync <LockHeldException>(async() => await lockKey.Acquire(CancellationToken.None)); Assert.True(lockKey.IsHeld); await lockKey.Release(); await Assert.ThrowsAsync <LockNotHeldException>(async() => await lockKey.Release()); Assert.False(lockKey.IsHeld); }
public async Task Lock_OneShot() { var client = new ConsulClient(); const string keyName = "test/lock/oneshot"; var lockOptions = new LockOptions(keyName) { LockTryOnce = true }; Assert.Equal(Lock.DefaultLockWaitTime, lockOptions.LockWaitTime); lockOptions.LockWaitTime = TimeSpan.FromMilliseconds(1000); var lockKey = client.CreateLock(lockOptions); await lockKey.Acquire(CancellationToken.None); var contender = client.CreateLock(new LockOptions(keyName) { LockTryOnce = true, LockWaitTime = TimeSpan.FromMilliseconds(1000) }); var stopwatch = Stopwatch.StartNew(); Assert.True(lockKey.IsHeld); Assert.False(contender.IsHeld); Assert.NotEqual(WaitHandle.WaitTimeout, Task.WaitAny( new Task[] { Task.Run(async() => { await Assert.ThrowsAsync <LockMaxAttemptsReachedException>(async() => await contender.Acquire()); }) }, (int)(2 * lockOptions.LockWaitTime.TotalMilliseconds))); Assert.False(stopwatch.ElapsedMilliseconds < lockOptions.LockWaitTime.TotalMilliseconds); Assert.False(contender.IsHeld, "Contender should have failed to acquire"); Assert.True(lockKey.IsHeld); Assert.False(contender.IsHeld); await lockKey.Release(); Assert.False(lockKey.IsHeld); Assert.False(contender.IsHeld); while (contender.IsHeld == false) { try { await contender.Acquire(); Assert.False(lockKey.IsHeld); Assert.True(contender.IsHeld); } catch (LockMaxAttemptsReachedException) { // Ignore because lock delay might be in effect. } } await contender.Release(); await contender.Destroy(); }
public void Lock_OneShot() { var client = new ConsulClient(); const string keyName = "test/lock/oneshot"; var lockOptions = new LockOptions(keyName) { LockTryOnce = true }; Assert.Equal(Lock.DefaultLockWaitTime, lockOptions.LockWaitTime); lockOptions.LockWaitTime = TimeSpan.FromMilliseconds(1000); var lockKey = client.CreateLock(lockOptions); lockKey.Acquire(CancellationToken.None); var contender = client.CreateLock(new LockOptions(keyName) { LockTryOnce = true, LockWaitTime = TimeSpan.FromMilliseconds(1000) }); var stopwatch = Stopwatch.StartNew(); Exception didExcept = null; Task.WaitAny( Task.Run(() => { // Needed because async asserts don't work in sync methods! try { contender.Acquire(); } catch (Exception e) { didExcept = e; } }), Task.Delay((int)(2 * lockOptions.LockWaitTime.TotalMilliseconds)).ContinueWith((t) => Assert.True(false, "Took too long")) ); Assert.False(stopwatch.ElapsedMilliseconds < lockOptions.LockWaitTime.TotalMilliseconds); Assert.False(contender.IsHeld, "Contender should have failed to acquire"); Assert.IsType<LockMaxAttemptsReachedException>(didExcept); lockKey.Release(); contender.Acquire(); Assert.True(contender.IsHeld); contender.Release(); contender.Destroy(); }
public void Lock_ForceInvalidate() { var client = new ConsulClient(); const string keyName = "test/lock/forceinvalidate"; var lockKey = (Lock)client.CreateLock(keyName); try { lockKey.Acquire(CancellationToken.None); Assert.True(lockKey.IsHeld); var checker = Task.Run(() => { while (lockKey.IsHeld) { Task.Delay(10).Wait(); } Assert.False(lockKey.IsHeld); }); Task.Run(() => { client.Session.Destroy(lockKey.LockSession); }); Task.WaitAny(new[] { checker }, 1000); } finally { try { lockKey.Release(); lockKey.Destroy(); } catch (LockNotHeldException ex) { Assert.IsType<LockNotHeldException>(ex); } } }
public void Lock_SemaphoreConflict() { var client = new ConsulClient(); const string keyName = "test/lock/semaphoreconflict"; var semaphore = client.Semaphore(keyName, 2); semaphore.Acquire(CancellationToken.None); Assert.True(semaphore.IsHeld); var lockKey = client.CreateLock(keyName + "/.lock"); try { lockKey.Acquire(CancellationToken.None); } catch (LockConflictException ex) { Assert.IsType<LockConflictException>(ex); } try { lockKey.Destroy(); } catch (LockConflictException ex) { Assert.IsType<LockConflictException>(ex); } semaphore.Release(); semaphore.Destroy(); }
public void Lock_OneShot() { var client = new ConsulClient(); const string keyName = "test/lock/oneshot"; var lockOptions = new LockOptions(keyName) { LockTryOnce = true }; Assert.Equal(Lock.DefaultLockWaitTime, lockOptions.LockWaitTime); lockOptions.LockWaitTime = TimeSpan.FromMilliseconds(250); var lockKey = client.CreateLock(lockOptions); lockKey.Acquire(CancellationToken.None); var contender = client.CreateLock(new LockOptions(keyName) { LockTryOnce = true, LockWaitTime = TimeSpan.FromMilliseconds(250) }); Task.WaitAny(Task.Run(() => { Assert.Throws<LockMaxAttemptsReachedException>(() => contender.Acquire() ); }), Task.Delay(2 * lockOptions.LockWaitTime.Milliseconds).ContinueWith((t) => Assert.True(false, "Took too long")) ); lockKey.Release(); contender.Acquire(); contender.Release(); contender.Destroy(); }