/// <summary>
        /// Gets the specified cacheKey async.
        /// </summary>
        /// <returns>The async.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public async Task <CacheValue <T> > GetAsync <T>(string cacheKey) where T : class
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

            var list = await _cache.QueryAsync <string>(ConstSQL.GETSQL, new
            {
                cachekey = cacheKey
            });

            var dbResult = list.FirstOrDefault();

            if (!string.IsNullOrWhiteSpace(dbResult))
            {
                return(new CacheValue <T>(Newtonsoft.Json.JsonConvert.DeserializeObject <T>(dbResult), true));
            }
            else
            {
                return(CacheValue <T> .NoValue);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Set the specified cacheKey, cacheValue and expiration.
        /// </summary>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="cacheValue">Cache value.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public void Set <T>(string cacheKey, T cacheValue, TimeSpan expiration)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

            _localCache.Set(cacheKey, cacheValue, expiration);

            try
            {
                _distributedCache.Set(cacheKey, cacheValue, expiration);
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "set cache key [{0}] error", cacheKey);
            }

            // When create/update cache, send message to bus so that other clients can remove it.
            _bus.Publish(_options.TopicName, new EasyCachingMessage {
                Id = _cacheId, CacheKeys = new string[] { cacheKey }
            });
        }
Beispiel #3
0
        /// <summary>
        /// Removes the by prefix.
        /// </summary>
        /// <param name="prefix">Prefix.</param>
        public void RemoveByPrefix(string prefix)
        {
            ArgumentCheck.NotNullOrWhiteSpace(prefix, nameof(prefix));

            try
            {
                _distributedCache.RemoveByPrefix(prefix);
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "remove by prefix [{0}] error", prefix);
            }

            _localCache.RemoveByPrefix(prefix);

            // send message to bus
            _bus.Publish(_options.TopicName, new EasyCachingMessage {
                Id = _cacheId, CacheKeys = new string[] { prefix }, IsPrefix = true
            });
        }
Beispiel #4
0
        /// <summary>
        /// Sets the async.
        /// </summary>
        /// <returns>The async.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="cacheValue">Cache value.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public async Task SetAsync <T>(string cacheKey, T cacheValue, TimeSpan expiration)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
            ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

            if (MaxRdSecond > 0)
            {
                var addSec = new Random().Next(1, MaxRdSecond);
                expiration = expiration.Add(TimeSpan.FromSeconds(addSec));
            }

            var val = _serializer.Serialize(cacheValue);

            await _cache.SetAsync(
                cacheKey,
                val,
                expiration.Seconds
                );
        }
Beispiel #5
0
        /// <summary>
        /// Get the specified cacheKey, dataRetriever and expiration.
        /// </summary>
        /// <returns>The get.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="dataRetriever">Data retriever.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public CacheValue <T> Get <T>(string cacheKey, Func <T> dataRetriever, TimeSpan expiration) where T : class
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

            var dbResult = _cache.Query <string>(ConstSQL.GETSQL, new
            {
                cachekey = cacheKey
            }).FirstOrDefault();

            if (!string.IsNullOrWhiteSpace(dbResult))
            {
                if (_options.EnableLogging)
                {
                    _logger?.LogInformation($"Cache Hit : cachekey = {cacheKey}");
                }

                CacheStats.OnHit();

                return(new CacheValue <T>(Newtonsoft.Json.JsonConvert.DeserializeObject <T>(dbResult), true));
            }

            CacheStats.OnMiss();

            if (_options.EnableLogging)
            {
                _logger?.LogInformation($"Cache Missed : cachekey = {cacheKey}");
            }

            var item = dataRetriever?.Invoke();

            if (item != null)
            {
                Set(cacheKey, item, expiration);
                return(new CacheValue <T>(item, true));
            }
            else
            {
                return(CacheValue <T> .NoValue);
            }
        }
Beispiel #6
0
        public long SAdd <T>(string cacheKey, IList <T> cacheValues, TimeSpan?expiration = null)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNullAndCountGTZero(cacheValues, nameof(cacheValues));

            var list = new List <RedisValue>();

            foreach (var item in cacheValues)
            {
                list.Add(_serializer.Serialize(item));
            }

            var len = _cache.SetAdd(cacheKey, list.ToArray());

            if (expiration.HasValue)
            {
                _cache.KeyExpire(cacheKey, expiration.Value);
            }

            return(len);
        }
        /// <summary>
        /// Set the specified cacheKey, cacheValue and expiration.
        /// </summary>
        /// <returns>The set.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="cacheValue">Cache value.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public override void BaseSet <T>(string cacheKey, T cacheValue, TimeSpan expiration)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
            ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

            if (MaxRdSecond > 0)
            {
                var addSec = new Random().Next(1, MaxRdSecond);
                expiration.Add(new TimeSpan(0, 0, addSec));
            }
            var exp = expiration.Ticks / 10000000;

            _cache.Upsert(new CacheItem
            {
                cachekey   = cacheKey,
                name       = _name,
                cachevalue = Newtonsoft.Json.JsonConvert.SerializeObject(cacheValue),
                expiration = expiration.Ticks / 10000000
            });
        }
        public async Task <long> SAddAsync <T>(string cacheKey, IList <T> cacheValues, TimeSpan?expiration = null)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNullAndCountGTZero(cacheValues, nameof(cacheValues));

            var list = new List <byte[]>();

            foreach (var item in cacheValues)
            {
                list.Add(_serializer.Serialize(item));
            }

            var len = await _cache.SAddAsync <byte[]>(cacheKey, list.ToArray());

            if (expiration.HasValue)
            {
                await _cache.ExpireAsync(cacheKey, expiration.Value.Seconds);
            }

            return(len);
        }
Beispiel #9
0
        /// <summary>
        /// Remove the specified cacheKey.
        /// </summary>
        /// <param name="cacheKey">Cache key.</param>
        public void Remove(string cacheKey)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

            try
            {
                // distributed cache at first
                _distributedCache.Remove(cacheKey);
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "remove cache key [{0}] error", cacheKey);
            }

            _localCache.Remove(cacheKey);

            // send message to bus
            _bus.Publish(_options.TopicName, new EasyCachingMessage {
                Id = _cacheId, CacheKeys = new string[] { cacheKey }
            });
        }
Beispiel #10
0
        /// <summary>
        /// Existses the specified cacheKey async.
        /// </summary>
        /// <returns>The async.</returns>
        /// <param name="cacheKey">Cache key.</param>
        public async Task <bool> ExistsAsync(string cacheKey)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

            bool flag;

            try
            {
                flag = await _distributedCache.ExistsAsync(cacheKey);

                return(flag);
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "Check cache key [{0}] exists error", cacheKey);
            }

            flag = await _localCache.ExistsAsync(cacheKey);

            return(flag);
        }
        /// <summary>
        /// Removes the specified cacheKey async.
        /// </summary>
        /// <returns>The async.</returns>
        /// <param name="cacheKey">Cache key.</param>
        public async Task RemoveAsync(string cacheKey)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

            try
            {
                // distributed cache at first
                await _distributedCache.RemoveAsync(cacheKey);
            }
            catch (Exception ex)
            {
                LogMessage($"remove cache key [{cacheKey}] error", ex);
            }

            await _localCache.RemoveAsync(cacheKey);

            // send message to bus
            await _busAsyncWrap.ExecuteAsync(async() => await _bus.PublishAsync(_options.TopicName, new EasyCachingMessage {
                Id = _cacheId, CacheKeys = new string[] { cacheKey }
            }));
        }
Beispiel #12
0
        /// <summary>
        /// Tries the set.
        /// </summary>
        /// <returns><c>true</c>, if set was tryed, <c>false</c> otherwise.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="cacheValue">Cache value.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public bool TrySet <T>(string cacheKey, T cacheValue, TimeSpan expiration)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

            bool distributedError = false;
            bool flag             = false;

            try
            {
                flag = _distributedCache.TrySet(cacheKey, cacheValue, expiration);
            }
            catch (Exception ex)
            {
                distributedError = true;
                _logger?.LogError(ex, "tryset cache key [{0}] error", cacheKey);
            }

            if (flag && !distributedError)
            {
                // When we TrySet succeed in distributed cache, we should Set this cache to local cache.
                // It's mainly to prevent the cache value was changed
                _localCache.Set(cacheKey, cacheValue, expiration);
            }

            // distributed cache occur error, have a try with local cache
            if (distributedError)
            {
                flag = _localCache.TrySet(cacheKey, cacheValue, expiration);
            }

            if (flag)
            {
                // Here should send message to bus due to cache was set successfully.
                _bus.Publish(_options.TopicName, new EasyCachingMessage {
                    Id = _cacheId, CacheKeys = new string[] { cacheKey }
                });
            }

            return(flag);
        }
        /// <summary>
        /// Tries the set async.
        /// </summary>
        /// <returns>The set async.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="cacheValue">Cache value.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public async Task <bool> TrySetAsync <T>(string cacheKey, T cacheValue, TimeSpan expiration)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

            bool distributedError = false;
            bool flag             = false;

            try
            {
                flag = await _distributedCache.TrySetAsync(cacheKey, cacheValue, expiration);
            }
            catch (Exception ex)
            {
                distributedError = true;
                LogMessage($"tryset cache key [{cacheKey}] error", ex);
            }

            if (flag && !distributedError)
            {
                // When we TrySet succeed in distributed cache, we should Set this cache to local cache.
                // It's mainly to prevent the cache value was changed
                await _localCache.SetAsync(cacheKey, cacheValue, expiration);
            }

            // distributed cache occur error, have a try with local cache
            if (distributedError)
            {
                flag = await _localCache.TrySetAsync(cacheKey, cacheValue, expiration);
            }

            if (flag)
            {
                // Here should send message to bus due to cache was set successfully.
                await _busAsyncWrap.ExecuteAsync(async() => await _bus.PublishAsync(_options.TopicName, new EasyCachingMessage {
                    Id = _cacheId, CacheKeys = new string[] { cacheKey }
                }));
            }

            return(flag);
        }
        /// <summary>
        /// Gets the specified cacheKey, dataRetriever and expiration async.
        /// </summary>
        /// <returns>The async.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="dataRetriever">Data retriever.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public async Task <CacheValue <T> > GetAsync <T>(string cacheKey, Func <Task <T> > dataRetriever, TimeSpan expiration) where T : class
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

            var result = await _cache.StringGetAsync(cacheKey);

            if (!result.IsNull)
            {
                CacheStats.OnHit();

                if (_options.EnableLogging)
                {
                    _logger?.LogInformation($"Cache Hit : cachekey = {cacheKey}");
                }

                var value = _serializer.Deserialize <T>(result);
                return(new CacheValue <T>(value, true));
            }

            CacheStats.OnMiss();

            if (_options.EnableLogging)
            {
                _logger?.LogInformation($"Cache Missed : cachekey = {cacheKey}");
            }

            var item = await dataRetriever?.Invoke();

            if (item != null)
            {
                await SetAsync(cacheKey, item, expiration);

                return(new CacheValue <T>(item, true));
            }
            else
            {
                return(CacheValue <T> .NoValue);
            }
        }
Beispiel #15
0
        /// <summary>
        /// Gets the by prefix.
        /// </summary>
        /// <returns>The by prefix.</returns>
        /// <param name="prefix">Prefix.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public IDictionary <string, CacheValue <T> > GetByPrefix <T>(string prefix) where T : class
        {
            ArgumentCheck.NotNullOrWhiteSpace(prefix, nameof(prefix));

            var map = new Dictionary <string, CacheValue <T> >();

            if (_options.EnableLogging)
            {
                _logger?.LogInformation($"GetByPrefix : prefix = {prefix}");
            }

            var keys = _cacheKeys.Where(x => x.StartsWith(prefix.Trim(), StringComparison.OrdinalIgnoreCase));

            if (keys.Any())
            {
                foreach (var item in keys)
                {
                    map[item] = this.Get <T>(item);
                }
            }
            return(map);
        }
        /// <summary>
        /// Get the specified cacheKey, dataRetriever and expiration.
        /// </summary>
        /// <returns>The get.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="dataRetriever">Data retriever.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public override CacheValue <T> BaseGet <T>(string cacheKey, Func <T> dataRetriever, TimeSpan expiration)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

            var redisValue = _cache.StringGet(cacheKey);
            var result     = Deserialize <T>(cacheKey, redisValue);

            TrackCacheStats(cacheKey, result);

            if (result.HasValue)
            {
                return(result);
            }

            if (!_cache.StringSet($"{cacheKey}_Lock", 1, TimeSpan.FromMilliseconds(_options.LockMs), When.NotExists))
            {
                System.Threading.Thread.Sleep(_options.SleepMs);
                return(Get(cacheKey, dataRetriever, expiration));
            }

            var item = dataRetriever();

            if (item != null || _options.CacheNulls)
            {
                Set(cacheKey, item, expiration);
                //remove mutex key
                _cache.KeyDelete($"{cacheKey}_Lock");
                result = new CacheValue <T>(item, true);
            }
            else
            {
                //remove mutex key
                _cache.KeyDelete($"{cacheKey}_Lock");
                result = CacheValue <T> .NoValue;
            }

            return(result);
        }
        /// <summary>
        /// Get the specified cacheKey, dataRetriever and expiration.
        /// </summary>
        /// <returns>The get.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="dataRetriever">Data retriever.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public CacheValue <T> Get <T>(string cacheKey, Func <T> dataRetriever, TimeSpan expiration) where T : class
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

            if (_memcachedClient.Get(this.HandleCacheKey(cacheKey)) is T result)
            {
                return(new CacheValue <T>(result, true));
            }

            var item = dataRetriever?.Invoke();

            if (item != null)
            {
                this.Set(cacheKey, item, expiration);
                return(new CacheValue <T>(item, true));
            }
            else
            {
                return(CacheValue <T> .NoValue);
            }
        }
        /// <summary>
        /// Gets the specified cacheKey, dataRetriever and expiration async.
        /// </summary>
        /// <returns>The async.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="dataRetriever">Data retriever.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public override async Task <CacheValue <T> > BaseGetAsync <T>(string cacheKey, Func <Task <T> > dataRetriever, TimeSpan expiration)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

            var result = await BaseGetAsync <T>(cacheKey);

            if (result.HasValue)
            {
                return(result);
            }

            var flag = await _memcachedClient.StoreAsync(Enyim.Caching.Memcached.StoreMode.Add,
                                                         this.HandleCacheKey($"{cacheKey}_Lock"), 1, TimeSpan.FromMilliseconds(_options.LockMs));

            if (!flag)
            {
                await Task.Delay(_options.SleepMs);

                return(await GetAsync(cacheKey, dataRetriever, expiration));
            }

            var item = await dataRetriever();

            if (item != null || _options.CacheNulls)
            {
                await this.SetAsync(cacheKey, item, expiration);

                await _memcachedClient.RemoveAsync(this.HandleCacheKey($"{cacheKey}_Lock"));

                return(new CacheValue <T>(item, true));
            }
            else
            {
                await _memcachedClient.RemoveAsync(this.HandleCacheKey($"{cacheKey}_Lock"));

                return(CacheValue <T> .NoValue);
            }
        }
Beispiel #19
0
        public List <bool> StringSetBit(string cacheKey, IEnumerable <long> offsets, bool value)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

            var results = new Task <bool> [offsets.Count()];

            var batch = _redisDb.CreateBatch();
            var index = 0;

            foreach (var position in offsets)
            {
                results[index] = batch.StringSetBitAsync(cacheKey, position, value);
                index++;
            }
            batch.Execute();
            if (!Task.WaitAll(results, TimeoutMilliseconds))
            {
                throw new TimeoutException();
            }

            return(results.Select(r => r.Result).ToList());
        }
Beispiel #20
0
        /// <summary>
        /// Get the specified cacheKey, dataRetriever and expiration.
        /// </summary>
        /// <returns>The get.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="dataRetriever">Data retriever.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public override CacheValue <T> BaseGet <T>(string cacheKey, Func <T> dataRetriever, TimeSpan expiration)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

            var result = BaseGet <T>(cacheKey);

            if (result.HasValue)
            {
                return(result);
            }

            var item = dataRetriever();

            if (item != null || _options.CacheNulls)
            {
                Set(cacheKey, item, expiration);
                result = new CacheValue <T>(item, true);
            }

            return(result);
        }
        /// <summary>
        /// Removes cached item by cachekey's prefix.
        /// </summary>
        /// <param name="prefix">Prefix.</param>
        public void RemoveByPrefix(string prefix)
        {
            ArgumentCheck.NotNullOrWhiteSpace(prefix, nameof(prefix));

            prefix = BuildCacheKey(Name, prefix);

            var keys = _cacheKeys.Where(x => x.StartsWith(prefix.Trim(), StringComparison.OrdinalIgnoreCase));

            if (_options.EnableLogging)
            {
                _logger?.LogInformation($"RemoveByPrefix : prefix = {prefix}");
            }

            if (keys.Any())
            {
                foreach (var item in keys)
                {
                    _cache.Remove(item);
                    _cacheKeys.TryRemove(item);
                }
            }
        }
        /// <summary>
        /// Get the specified cacheKey, dataRetriever and expiration.
        /// </summary>
        /// <returns>The get.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="dataRetriever">Data retriever.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public CacheValue <T> Get <T>(string cacheKey, Func <T> dataRetriever, TimeSpan expiration) where T : class
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

            if (_cache.Get(cacheKey) is T result)
            {
                return(new CacheValue <T>(result, true));
            }

            result = dataRetriever?.Invoke();

            if (result != null)
            {
                Set(cacheKey, result, expiration);
                return(new CacheValue <T>(result, true));
            }
            else
            {
                return(CacheValue <T> .NoValue);
            }
        }
Beispiel #23
0
        /// <summary>
        /// Removes cached item by cachekey's prefix async.
        /// </summary>
        /// <returns>The by prefix async.</returns>
        /// <param name="prefix">Prefix.</param>
        public async Task RemoveByPrefixAsync(string prefix)
        {
            ArgumentCheck.NotNullOrWhiteSpace(prefix, nameof(prefix));

            var keys = _cacheKeys.Where(x => x.StartsWith(prefix.Trim(), StringComparison.OrdinalIgnoreCase));

            if (_options.EnableLogging)
            {
                _logger?.LogInformation($"RemoveByPrefixAsync : prefix = {prefix}");
            }

            if (keys.Any())
            {
                var tasks = new List <Task>();
                foreach (var item in keys)
                {
                    tasks.Add(RemoveAsync(item));
                }

                await Task.WhenAll(tasks);
            }
        }
        /// <summary>
        /// Tries the set.
        /// </summary>
        /// <returns><c>true</c>, if set was tryed, <c>false</c> otherwise.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="cacheValue">Cache value.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public override bool BaseTrySet <T>(string cacheKey, T cacheValue, TimeSpan expiration)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNull(cacheValue, nameof(cacheValue), _options.CacheNulls);
            ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

            if (MaxRdSecond > 0)
            {
                var addSec = new Random().Next(1, MaxRdSecond);
                expiration.Add(new TimeSpan(0, 0, addSec));
            }

            var rows = _cache.Execute(ConstSQL.TRYSETSQL, new
            {
                cachekey   = cacheKey,
                name       = _name,
                cachevalue = Newtonsoft.Json.JsonConvert.SerializeObject(cacheValue),
                expiration = expiration.Ticks / 10000000
            });

            return(rows > 0);
        }
        /// <summary>
        /// Existses the specified cacheKey async.
        /// </summary>
        /// <returns>The async.</returns>
        /// <param name="cacheKey">Cache key.</param>
        public async Task <bool> ExistsAsync(string cacheKey)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

            bool flag;

            // Circuit Breaker may be more better
            try
            {
                flag = await _distributedCache.ExistsAsync(cacheKey);

                return(flag);
            }
            catch (Exception ex)
            {
                LogMessage($"Check cache key [{cacheKey}] exists error", ex);
            }

            flag = await _localCache.ExistsAsync(cacheKey);

            return(flag);
        }
        /// <summary>
        /// Removes the by prefix async.
        /// </summary>
        /// <returns>The by prefix async.</returns>
        /// <param name="prefix">Prefix.</param>
        public async Task RemoveByPrefixAsync(string prefix)
        {
            ArgumentCheck.NotNullOrWhiteSpace(prefix, nameof(prefix));

            prefix = this.HandlePrefix(prefix);

            if (_options.EnableLogging)
            {
                _logger?.LogInformation($"RemoveByPrefixAsync : prefix = {prefix}");
            }

            var redisKeys = this.SearchRedisKeys(prefix);

            var tasks = new List <Task <long> >();

            foreach (var item in redisKeys)
            {
                tasks.Add(_cache.DelAsync(item));
            }

            await Task.WhenAll(tasks);
        }
        /// <summary>
        /// Gets the specified cacheKey, dataRetriever and expiration async.
        /// </summary>
        /// <returns>The async.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="dataRetriever">Data retriever.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public async Task <CacheValue <T> > GetAsync <T>(string cacheKey, Func <Task <T> > dataRetriever, TimeSpan expiration)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

            var result = await _memcachedClient.GetValueAsync <T>(this.HandleCacheKey(cacheKey));

            if (result != null)
            {
                CacheStats.OnHit();

                if (_options.EnableLogging)
                {
                    _logger?.LogInformation($"Cache Hit : cachekey = {cacheKey}");
                }

                return(new CacheValue <T>(result, true));
            }

            CacheStats.OnMiss();

            if (_options.EnableLogging)
            {
                _logger?.LogInformation($"Cache Missed : cachekey = {cacheKey}");
            }

            var item = await dataRetriever?.Invoke();

            if (item != null)
            {
                await this.SetAsync(cacheKey, item, expiration);

                return(new CacheValue <T>(item, true));
            }
            else
            {
                return(CacheValue <T> .NoValue);
            }
        }
Beispiel #28
0
        public static async Task <bool> SafedUnLockAsync(this IDatabase redisDb, string cacheKey, string lockValue)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNullOrWhiteSpace(lockValue, nameof(lockValue));

            var lockKey = GetLockKey(cacheKey);

            AutoDelayTimers.Instance.CloseTimer(lockKey);

            var script     = @"local invalue = @value 
                                    local currvalue = redis.call('get',@key) 
                                    if(invalue==currvalue) then redis.call('del',@key) 
                                        return 1
                                    else
                                        return 0
                                    end";
            var parameters = new { key = lockKey, value = lockValue };
            var prepared   = LuaScript.Prepare(script);
            var result     = (int)await redisDb.ScriptEvaluateAsync(prepared, parameters);

            return(result == 1);
        }
        /// <summary>
        /// Get the specified cacheKey, dataRetriever and expiration.
        /// </summary>
        /// <returns>The get.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="dataRetriever">Data retriever.</param>
        /// <param name="expiration">Expiration.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public override CacheValue <T> BaseGet <T>(string cacheKey, Func <T> dataRetriever, TimeSpan expiration)
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
            ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

            var dbResult = _cache.FindOne(c => c.cachekey == cacheKey)?.cachevalue;

            if (!string.IsNullOrWhiteSpace(dbResult))
            {
                if (_options.EnableLogging)
                {
                    _logger?.LogInformation($"Cache Hit : cachekey = {cacheKey}");
                }

                CacheStats.OnHit();

                return(new CacheValue <T>(Newtonsoft.Json.JsonConvert.DeserializeObject <T>(dbResult), true));
            }

            CacheStats.OnMiss();

            if (_options.EnableLogging)
            {
                _logger?.LogInformation($"Cache Missed : cachekey = {cacheKey}");
            }

            var item = dataRetriever();

            if (item != null)
            {
                Set(cacheKey, item, expiration);
                return(new CacheValue <T>(item, true));
            }
            else
            {
                return(CacheValue <T> .NoValue);
            }
        }
Beispiel #30
0
        /// <summary>
        /// Get the specified cacheKey.
        /// </summary>
        /// <returns>The get.</returns>
        /// <param name="cacheKey">Cache key.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public CacheValue <T> Get <T>(string cacheKey) where T : class
        {
            ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

            if (_memcachedClient.Get(this.HandleCacheKey(cacheKey)) is T result)
            {
                if (_options.EnableLogging)
                {
                    _logger?.LogInformation($"Cache Hit : cachekey = {cacheKey}");
                }

                return(new CacheValue <T>(result, true));
            }
            else
            {
                if (_options.EnableLogging)
                {
                    _logger?.LogInformation($"Cache Missed : cachekey = {cacheKey}");
                }

                return(CacheValue <T> .NoValue);
            }
        }