Ejemplo n.º 1
0
        public async Task ReleaseTestMethod()
        {
            using var @lock = _lockFactory.CreateLock("test", Guid.NewGuid().ToString());
            Assert.True(await @lock.LockAsync(60000).ConfigureAwait(false));

            await @lock.ReleaseAsync().ConfigureAwait(false);
        }
        public ILockService CreateLock(string resource, TimeSpan expiryTime)
        {
            var redLock = _lockFactory.CreateLock(resource, expiryTime);

            HandleRedLock(resource, redLock);
            return(this);
        }
Ejemplo n.º 3
0
        public async Task Concurrency_Test()
        {
            ThreadPool.SetMinThreads(1000, 1000);

            var random  = new Random();
            var key     = Guid.NewGuid().ToString("N");
            var counter = 0;

            using var @lock = Factory.CreateLock("test", Guid.NewGuid().ToString());

            await Task.WhenAll(Enumerable.Range(0, 100)
                               .Select(_ => Task.Run(async() =>
            {
                for (var index = 0; index < 1000; index++)
                {
                    var value = Interlocked.Increment(ref counter);

                    try
                    {
                        Assert.True(await @lock.LockAsync(15000, CancellationToken.None), value.ToString());

                        await Task.Delay(random.Next(0, 10));

                        await @lock.ReleaseAsync().ConfigureAwait(false);
                    }
                    catch (DistributedLockException)
                    {
                    }
                }
            })));
        }
Ejemplo n.º 4
0
        public void Lock_Release()
        {
            var @lock = _lockFactory.CreateLock(_name, Guid.NewGuid().ToString());

            try
            {
                Assert.True(@lock.Lock(60000));
            }
            finally
            {
                @lock.Release();
            }
        }
Ejemplo n.º 5
0
 public bool TryGetLock(string key, int timeoutMinutes)
 {
     lock (SyncLock)
     {
         this.lockObject = lockFactory.CreateLock(
             key,
             TimeSpan.FromMinutes(timeoutMinutes),
             this.WaitTime,
             this.RetryTime
             );
         return(this.lockObject.IsAcquired);
     }
 }
Ejemplo n.º 6
0
        public TV GetOrSet <TK, TV>(TK key, Func <TK, TimeSpan, CancellationToken, TV> func, TimeSpan expiry, CancellationToken token)
        {
            if (func == null)
            {
                throw new ArgumentNullException(nameof(func));
            }

            var formattedKey = ParseKey(key);

            var result = _provider.Get(formattedKey, token);

            if (result.HasValue)
            {
                return(_serializer.Deserialize <TV>(result.Value));
            }

            using var @lock = _factory.CreateLock($"{_options.KeyPrefix}/Lock/{_name}", formattedKey);

            if ([email protected](_options.LockTimeout * 1000, token))
            {
                throw new TimeoutException(Res.Wait_Lock_Timeout);
            }

            result = _provider.Get(formattedKey, token) !;
            if (result.HasValue)
            {
                return(_serializer.Deserialize <TV>(result.Value));
            }

            var value = func(key, expiry, token);

            _provider.Set(formattedKey, Serialize(value), GetTtl(expiry), When.Always, token);

            @lock.Release();

            return(value);
        }
Ejemplo n.º 7
0
        public IResourceLocker CreateLocker(string resource)
        {
            var locker = distributedLockFactory.CreateLock(resource, LockTime);

            return(new ResourceLocker(locker));
        }
        public CacheValue <T> Get <T>(string cacheKey, Func <T> dataRetriever, TimeSpan expiration)
        {
            var       operationId = s_diagnosticListener.WriteGetCacheBefore(new BeforeGetRequestEventData(CachingProviderType.ToString(), Name, nameof(Get), new[] { cacheKey }, expiration));
            Exception e           = null;

            try
            {
                if (_lockFactory == null)
                {
                    return(BaseGet <T>(cacheKey, dataRetriever, expiration));
                }

                var value = BaseGet <T>(cacheKey);
                if (value.HasValue)
                {
                    return(value);
                }

                using (var @lock = _lockFactory.CreateLock(Name, $"{cacheKey}_Lock"))
                {
                    if ([email protected](_options.SleepMs))
                    {
                        throw new TimeoutException();
                    }

                    value = BaseGet <T>(cacheKey);
                    if (value.HasValue)
                    {
                        return(value);
                    }

                    var item = dataRetriever();
                    if (item != null || _options.CacheNulls)
                    {
                        BaseSet(cacheKey, item, expiration);

                        return(new CacheValue <T>(item, true));
                    }
                    else
                    {
                        return(CacheValue <T> .NoValue);
                    }
                }
            }
            catch (Exception ex)
            {
                e = ex;
                throw;
            }
            finally
            {
                if (e != null)
                {
                    s_diagnosticListener.WriteGetCacheError(operationId, e);
                }
                else
                {
                    s_diagnosticListener.WriteGetCacheAfter(operationId);
                }
            }
        }
        public async Task SubscribeAsync <T>(Action <T> callBack, bool enableLock) where T : IMessage
        {
            if (enableLock && _distributedLockFactory == null)
            {
                throw new ArgumentNullException(nameof(_distributedLockFactory), "IDistributedLockFactory must be set in constructor if lock is enabled");
            }

            //Register subscriber
            var eventType        = typeof(T).Name;
            var eventKey         = $"{_environment}:{eventType}";
            var subscriberSetKey = $"Subscribers:{{{eventKey}}}";
            var publishedListKey = $"{_applicationName}:{{{eventKey}}}:PublishedEvents";
            await _redisClient.SetAddAsync(subscriberSetKey, _applicationName).ConfigureAwait(false);

            //Create subscription callback
            void RedisCallback(RedisChannel channel, RedisValue data)
            {
                try
                {
                    if (enableLock)
                    {
                        using (var distributedLock = _distributedLockFactory.CreateLock(
                                   eventKey,
                                   TimeSpan.FromSeconds(_lockSettings.ExpirySeconds),
                                   TimeSpan.FromSeconds(_lockSettings.WaitSeconds),
                                   TimeSpan.FromMilliseconds(_lockSettings.RetryMilliseconds)))
                        {
                            if (distributedLock.IsAcquired)
                            {
                                ExecuteCallback(callBack);
                            }
                            else
                            {
                                throw new DistributedLockException(distributedLock, _lockSettings);
                            }
                        }
                    }
                    else
                    {
                        ExecuteCallback(callBack);
                    }
                }
                catch (Exception e)
                {
#if !NET46 && !NET452
                    _logger?.LogError($"{e.Message}\n{e.StackTrace}", e);
#endif
                    throw;
                }
            }

            //Subscribe to the event
            await _redisClient.SubscribeAsync(eventKey, RedisCallback).ConfigureAwait(false);

            //Grab any unprocessed events and process them
            //Ensures that events that were fired before the application was started will be picked up
            var awaitingEvents = await _redisClient.ListLengthAsync(publishedListKey).ConfigureAwait(false);

            for (var i = 0; i < awaitingEvents; i++)
            {
                try
                {
                    await Task.Run(() => RedisCallback(eventKey, true)).ConfigureAwait(false);
                }
                catch (Exception e)
                {
#if !NET46 && !NET452
                    _logger.LogError(e, e.Message);
#endif
                }
            }
        }