Ejemplo n.º 1
0
        /// <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 _memcachedClient.GetAsync <T>(this.HandleCacheKey(cacheKey));

            if (result.Success)
            {
                CacheStats.OnHit();

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

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

            CacheStats.OnMiss();

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

            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)
            {
                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);
            }
        }
        /// <summary>
        /// Sets the specified cacheKey, cacheValue and expiration 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.Add(new TimeSpan(0, 0, addSec));
            }

            await _memcachedClient.StoreAsync(Enyim.Caching.Memcached.StoreMode.Set, this.HandleCacheKey(cacheKey), cacheValue, expiration);
        }