Пример #1
0
        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();
                        }
                    });
                }
            }
        }
Пример #2
0
        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");
                }
            }
        }
Пример #3
0
        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);
                }
            }
        }
Пример #4
0
        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));
        }
Пример #5
0
        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));
                }
            }
        }
Пример #6
0
        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
                    }
                }
            }
        }
Пример #7
0
        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);
        }
Пример #9
0
        /// <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);
            }
        }
Пример #10
0
 /// <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);
     }
 }
Пример #11
0
        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));
        }
Пример #12
0
        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));
            }
        }