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); }
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) { } } }))); }
public void Lock_Release() { var @lock = _lockFactory.CreateLock(_name, Guid.NewGuid().ToString()); try { Assert.True(@lock.Lock(60000)); } finally { @lock.Release(); } }
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); } }
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); }
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 } } }