Beispiel #1
0
        public RedisLockTests()
        {
            var muxer = ConnectionMultiplexer.Connect(Settings.Current.RedisConnectionString);

            _cacheClient = new RedisCacheClient(muxer);
            _locker      = new CacheLockProvider(_cacheClient);
        }
        public RedisLockTests()
        {
            var muxer = ConnectionMultiplexer.Connect(Settings.Current.RedisConnectionInfo.ToString());

            _cacheClient = new RedisCacheClient(muxer.GetDatabase());
            _locker      = new CacheLockProvider(_cacheClient);
        }
        private async Task StartInternalAsync(
            string lockName,
            LockLostBehavior lockLostBehavior,
            CancellationToken cancellationToken)
        {
            _log.TraceMethodEntry();

            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }

            var lockTimeout = TimeSpan.FromSeconds(5);

            using (var inMemoryLockCacheClient = new InMemoryCacheClient())
                using (var distributedLockCacheClient = new HybridCacheClient(inMemoryLockCacheClient, _messageBus))
                {
                    var lockProvider = new CacheLockProvider(distributedLockCacheClient, _messageBus);

                    while (!cancellationToken.IsCancellationRequested)
                    {
                        var lockHandle = await lockProvider.AcquireAsync(
                            lockName,
                            lockTimeout,
                            cancellationToken)
                                         .ConfigureAwait(false);

                        if (lockHandle != null)
                        {
                            try
                            {
                                // we have the lock
                                // keep renewing it
                                await HoldAndRenewAsync(
                                    lockHandle,
                                    cancellationToken)
                                .ConfigureAwait(false);
                            }
                            catch (Exception e)
                            {
                                switch (lockLostBehavior)
                                {
                                case LockLostBehavior.Complete:
                                    return;

                                case LockLostBehavior.Error:
                                    throw new LockLostException(lockName, e);

                                case LockLostBehavior.Retry:
                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                    }
                }
        }
Beispiel #4
0
        public static Configuration UseFoundatioLockInMemory(this Configuration configuration)
        {
            ILockProvider lockerProvider = new CacheLockProvider(new InMemoryCacheClient(), new InMemoryMessageBus());

            IoCFactory.Instance.CurrentContainer
            .RegisterInstance(typeof(Infrastructure.ILockProvider), new LockProvider(lockerProvider));
            return(configuration);
        }
Beispiel #5
0
        public static Configuration UseFoundatioLockRedis(this Configuration configuration, string redisConnectionString = null, bool preserveAsyncOrder = false)
        {
            ConnectionMultiplexer muxer          = GetMuxer(redisConnectionString, preserveAsyncOrder);
            ILockProvider         lockerProvider = new CacheLockProvider(new RedisCacheClient(muxer), new RedisMessageBus(muxer.GetSubscriber()));

            IoCFactory.Instance.CurrentContainer
            .RegisterInstance(typeof(Infrastructure.ILockProvider), new FoundatioLock.LockProvider(lockerProvider));
            return(configuration);
        }
Beispiel #6
0
 public virtual async Task CanHaveMultipleQueueInstancesWithLockingAsync()
 {
     using (var cache = new InMemoryCacheClient(Log)) {
         using (var messageBus = new InMemoryMessageBus(Log)) {
             var distributedLock = new CacheLockProvider(cache, messageBus, Log);
             await CanHaveMultipleQueueInstancesWithLockingImplAsync(distributedLock);
         }
     }
 }
Beispiel #7
0
        public override async Task CanHaveMultipleQueueInstancesWithLockingAsync()
        {
            var muxer = SharedConnection.GetMuxer();

            using var cache      = new RedisCacheClient(new RedisCacheClientOptions { ConnectionMultiplexer = muxer, LoggerFactory = Log });
            using var messageBus = new RedisMessageBus(new RedisMessageBusOptions { Subscriber = muxer.GetSubscriber(), Topic = "test-queue", LoggerFactory = Log });
            var distributedLock = new CacheLockProvider(cache, messageBus, Log);

            await CanHaveMultipleQueueInstancesWithLockingImplAsync(distributedLock);
        }
Beispiel #8
0
        public override async Task CanHaveMultipleQueueInstancesWithLockingAsync()
        {
            var muxer = SharedConnection.GetMuxer();

            using (var cache = new RedisCacheClient(muxer, loggerFactory: Log)) {
                using (var messageBus = new RedisMessageBus(muxer.GetSubscriber(), "test", loggerFactory: Log)) {
                    var distributedLock = new CacheLockProvider(cache, messageBus, Log);
                    await CanHaveMultipleQueueInstancesWithLockingImplAsync(distributedLock);
                }
            }
        }
Beispiel #9
0
        protected ReadModelProjectorBase3(ILoggerFactory loggerFactory, IProjectorServices services) : base(loggerFactory, services)
        {
            LockProvider = new CacheLockProvider(
                new InMemoryCacheClient(builder => builder.LoggerFactory(loggerFactory))
                , new InMemoryMessageBus(builder => builder.LoggerFactory(loggerFactory)), loggerFactory);
            //LockProvider = services.LockProvider;

            var ent = Activator.CreateInstance <T>();

            EntityTypeKey = ent.EntityType;
        }
Beispiel #10
0
 public virtual async Task CanDequeueWithLockingAsync()
 {
     using (var cache = new InMemoryCacheClient(new InMemoryCacheClientOptions {
         LoggerFactory = Log
     })) {
         using (var messageBus = new InMemoryMessageBus(new InMemoryMessageBusOptions {
             LoggerFactory = Log
         })) {
             var distributedLock = new CacheLockProvider(cache, messageBus, Log);
             await CanDequeueWithLockingImpAsync(distributedLock);
         }
     }
 }
Beispiel #11
0
        protected async Task CanDequeueWithLockingImpAsync(CacheLockProvider distributedLock)
        {
            var queue = GetQueue(retryDelay: TimeSpan.Zero, retries: 0);

            if (queue == null)
            {
                return;
            }

            try {
                await queue.DeleteQueueAsync();
                await AssertEmptyQueueAsync(queue);

                using (var metrics = new InMemoryMetricsClient(new InMemoryMetricsClientOptions {
                    Buffered = false, LoggerFactory = Log
                })) {
                    queue.AttachBehavior(new MetricsQueueBehavior <SimpleWorkItem>(metrics, loggerFactory: Log));

                    var resetEvent = new AsyncAutoResetEvent();
                    await queue.StartWorkingAsync(async w => {
                        _logger.Info("Acquiring distributed lock in work item");
                        var l = await distributedLock.AcquireAsync("test");
                        Assert.NotNull(l);
                        _logger.Info("Acquired distributed lock");
                        SystemClock.Sleep(TimeSpan.FromMilliseconds(250));
                        await l.ReleaseAsync();
                        _logger.Info("Released distributed lock");

                        await w.CompleteAsync();
                        resetEvent.Set();
                    });

                    await queue.EnqueueAsync(new SimpleWorkItem { Data = "Hello" });

                    await resetEvent.WaitAsync(TimeSpan.FromSeconds(5).ToCancellationToken());

                    await SystemClock.SleepAsync(1);

                    var stats = await queue.GetQueueStatsAsync();

                    _logger.Info("Completed: {completed} Errors: {errors} Deadletter: {deadletter} Working: {working} ", stats.Completed, stats.Errors, stats.Deadletter, stats.Working);
                    Assert.Equal(1, stats.Completed);
                }
            }
            finally {
                await CleanupQueueAsync(queue);
            }
        }
Beispiel #12
0
        protected async Task CanHaveMultipleQueueInstancesWithLockingImplAsync(CacheLockProvider distributedLock)
        {
            var queue = GetQueue(retries: 0, retryDelay: TimeSpan.Zero);

            if (queue == null)
            {
                return;
            }

            try {
                await queue.DeleteQueueAsync();
                await AssertEmptyQueueAsync(queue);

                const int workItemCount = 16;
                const int workerCount   = 4;
                var       countdown     = new AsyncCountdownEvent(workItemCount);
                var       info          = new WorkInfo();
                var       workers       = new List <IQueue <SimpleWorkItem> > {
                    queue
                };

                try {
                    for (int i = 0; i < workerCount; i++)
                    {
                        var q             = GetQueue(retries: 0, retryDelay: TimeSpan.Zero);
                        int instanceCount = i;
                        await q.StartWorkingAsync(async w => {
                            _logger.Info("[{0}] Acquiring distributed lock in work item: {1}", instanceCount, w.Id);
                            var l = await distributedLock.AcquireAsync("test");
                            Assert.NotNull(l);
                            _logger.Info("[{0}] Acquired distributed lock: {1}", instanceCount, w.Id);
                            SystemClock.Sleep(TimeSpan.FromMilliseconds(50));
                            await l.ReleaseAsync();
                            _logger.Info("[{0}] Released distributed lock: {1}", instanceCount, w.Id);

                            await w.CompleteAsync();
                            info.IncrementCompletedCount();
                            countdown.Signal();
                            _logger.Info("[{0}] Signaled countdown: {1}", instanceCount, w.Id);
                        });

                        workers.Add(q);
                    }

                    await Run.InParallelAsync(workItemCount, async i => {
                        string id = await queue.EnqueueAsync(new SimpleWorkItem {
                            Data = "Hello",
                            Id   = i
                        });
                        _logger.Trace("Enqueued Index: {0} Id: {1}", i, id);
                    });

                    await countdown.WaitAsync(TimeSpan.FromSeconds(5).ToCancellationToken());

                    await SystemClock.SleepAsync(50);

                    _logger.Trace("Completed: {0} Abandoned: {1} Error: {2}", info.CompletedCount, info.AbandonCount, info.ErrorCount);

                    _logger.Info("Work Info Stats: Completed: {completed} Abandoned: {abandoned} Error: {errors}", info.CompletedCount, info.AbandonCount, info.ErrorCount);
                    Assert.Equal(workItemCount, info.CompletedCount + info.AbandonCount + info.ErrorCount);

                    // In memory queue doesn't share state.
                    if (queue.GetType() == typeof(InMemoryQueue <SimpleWorkItem>))
                    {
                        var stats = await queue.GetQueueStatsAsync();

                        Assert.Equal(info.CompletedCount, stats.Completed);
                    }
                    else
                    {
                        var workerStats = new List <QueueStats>();
                        for (int i = 0; i < workers.Count; i++)
                        {
                            var stats = await workers[i].GetQueueStatsAsync();
                            _logger.Info("Worker#{i} Working: {working} Completed: {completed} Abandoned: {abandoned} Error: {errors} Deadletter: {deadletter}", i, stats.Working, stats.Completed, stats.Abandoned, stats.Errors, stats.Deadletter);
                            workerStats.Add(stats);
                        }

                        Assert.Equal(info.CompletedCount, workerStats.Sum(s => s.Completed));
                    }
                } finally {
                    foreach (var q in workers)
                    {
                        await CleanupQueueAsync(q);
                    }
                }
            } finally {
                await CleanupQueueAsync(queue);
            }
        }