public void TestCancelBlockingLock() { var cts = new CancellationTokenSource(); var resource = $"testredislock-{Guid.NewGuid()}"; using (var redisLockFactory = new RedisLockFactory(AllActiveEndPoints)) { using (var firstLock = redisLockFactory.Create( resource, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(1))) { Assert.That(firstLock.IsAcquired); cts.CancelAfter(TimeSpan.FromSeconds(2)); Assert.Throws <OperationCanceledException>(() => { using (var secondLock = redisLockFactory.Create( resource, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(1), cts.Token)) { // should never get here Assert.Fail(); } }); } } }
public void TimeLock() { using (var redisLockFactory = new RedisLockFactory(AllActiveEndPoints)) { var resource = $"testredislock-{Guid.NewGuid()}"; for (var i = 0; i < 10; i++) { var sw = Stopwatch.StartNew(); using (var redisLock = redisLockFactory.Create(resource, TimeSpan.FromSeconds(30))) { sw.Stop(); Logger.Info($"Acquire {i} took {sw.ElapsedTicks} ticks, success {redisLock.IsAcquired}"); sw.Restart(); } sw.Stop(); Logger.Info($"Release {i} took {sw.ElapsedTicks} ticks, success"); } } }
public void TestSequentialLocks() { using (var redisLockFactory = new RedisLockFactory(AllActiveEndPoints)) { var resource = $"testredislock-{Guid.NewGuid()}"; using (var firstLock = redisLockFactory.Create(resource, TimeSpan.FromSeconds(30))) { Assert.That(firstLock.IsAcquired, Is.True); } using (var secondLock = redisLockFactory.Create(resource, TimeSpan.FromSeconds(30))) { Assert.That(secondLock.IsAcquired, Is.True); } } }
public void TestRaceForQuorum() { var locksAcquired = 0; var lockKey = $"testredislock-{ThreadSafeRandom.Next(10000)}"; var tasks = new List <Task>(); for (var i = 0; i < 3; i++) { var task = new Task(() => { Logger.Debug("Starting task"); using (var redisLockFactory = new RedisLockFactory(AllActiveEndPoints)) { var sw = Stopwatch.StartNew(); using (var redisLock = redisLockFactory.Create(lockKey, TimeSpan.FromSeconds(30))) { sw.Stop(); Logger.Debug($"Lock method took {sw.ElapsedMilliseconds}ms to return, IsAcquired = {redisLock.IsAcquired}"); if (redisLock.IsAcquired) { Logger.Debug($"Got lock with id {redisLock.LockId}, sleeping for a bit"); Interlocked.Increment(ref locksAcquired); // Sleep for long enough for the other threads to give up //Thread.Sleep(TimeSpan.FromSeconds(2)); Task.Delay(TimeSpan.FromSeconds(2)).Wait(); Logger.Debug($"Lock with id {redisLock.LockId} done sleeping"); } else { Logger.Debug("Couldn't get lock, giving up"); } } } }, TaskCreationOptions.LongRunning); tasks.Add(task); } foreach (var task in tasks) { task.Start(); } Task.WaitAll(tasks.ToArray()); Assert.That(locksAcquired, Is.EqualTo(1)); }
private static void CheckSingleRedisLock(IEnumerable <RedisLockEndPoint> endPoints, bool expectedToAcquire) { using (var redisLockFactory = new RedisLockFactory(endPoints)) { var resource = $"testredislock-{Guid.NewGuid()}"; using (var redisLock = redisLockFactory.Create(resource, TimeSpan.FromSeconds(30))) { Assert.That(redisLock.IsAcquired, Is.EqualTo(expectedToAcquire)); } } }
public void TestLockReleasedAfterTimeout() { using (var lockFactory = new RedisLockFactory(AllActiveEndPoints)) { var resource = $"testrenewinglock-{Guid.NewGuid()}"; using (var firstLock = lockFactory.Create(resource, TimeSpan.FromSeconds(1))) { Assert.That(firstLock.IsAcquired, Is.True); Thread.Sleep(550); // should cause keep alive timer to fire once ((RedisLock)firstLock).StopKeepAliveTimer(); // stop the keep alive timer to simulate process crash Thread.Sleep(1200); // wait until the key expires from redis using (var secondLock = lockFactory.Create(resource, TimeSpan.FromSeconds(1))) { Assert.That(secondLock.IsAcquired, Is.True); // Eventually the outer lock should timeout } } } }
public bool PerformActionWithLock(string resource, TimeSpan expirationTime, Action action) { using (var redisLock = _redisLockFactory.Create(resource, expirationTime)) { //确认取得分布式锁 if (!redisLock.IsAcquired) { return(false); } action(); return(true); } }
public bool Execute(string key, Action action, double expirySec = 2) { RedisLockFactory redLockFactory = GetLockFactory(); using (var redisLock = redLockFactory.Create(key, TimeSpan.FromSeconds(expirySec))) { if (redisLock.IsAcquired) { action(); return(true); } } return(false); }
/// <summary> /// Perform some action with Redis distributed lock /// </summary> /// <param name="resource">The thing we are locking on</param> /// <param name="expirationTime">The time after which the lock will automatically be expired by Redis</param> /// <param name="action">Action to be performed with locking</param> /// <returns>True if lock was acquired and action was performed; otherwise false</returns> public bool PerformActionWithLock(string resource, TimeSpan expirationTime, Action action) { //use RedLock library using (var redisLock = _redisLockFactory.Create(resource, expirationTime)) { //ensure that lock is acquired if (!redisLock.IsAcquired) { return(false); } //perform action action(); return(true); } }
/// <summary> /// 跳过式调用,如果事情正在被调用,直接跳过 /// </summary> /// <param name="resource">锁定资源的标识</param> /// <param name="expiryTime">锁过期时间</param> /// <param name="work"></param> public bool OverlappingWork(string resource, TimeSpan expiryTime, Action work) { resource = this.CreateKey(resource); using (var redisLockFactory = new RedisLockFactory(redisLockEndPoints)) { using (var redisLock = redisLockFactory.Create(resource, expiryTime)) { if (redisLock.IsAcquired) { work.Invoke(); return(true); } } return(false); } }
public void TestBlockingConcurrentLocks() { var locksAcquired = 0; using (var redisLockFactory = new RedisLockFactory(AllActiveEndPoints)) { var resource = $"testblockingconcurrentlocks-{Guid.NewGuid()}"; var threads = new List <Thread>(); for (var i = 0; i < 2; i++) { var thread = new Thread(() => { // ReSharper disable once AccessToDisposedClosure (we join on threads before disposing) using (var redisLock = redisLockFactory.Create( resource, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(0.5))) { Logger.Info("Entering lock"); if (redisLock.IsAcquired) { Interlocked.Increment(ref locksAcquired); } Thread.Sleep(4000); Logger.Info("Leaving lock"); } }); thread.Start(); threads.Add(thread); } foreach (var thread in threads) { thread.Join(); } } Assert.That(locksAcquired, Is.EqualTo(2)); }
public void TestRenewing() { using (var redisLockFactory = new RedisLockFactory(AllActiveEndPoints)) { var resource = $"testrenewinglock-{Guid.NewGuid()}"; int extendCount; using (var redisLock = redisLockFactory.Create(resource, TimeSpan.FromSeconds(2))) { Assert.That(redisLock.IsAcquired, Is.True); Thread.Sleep(4000); extendCount = redisLock.ExtendCount; } Assert.That(extendCount, Is.GreaterThan(2)); } }