public IRedisCacheService RedisCacheServiceFactory(ServiceCacheAttribute svcCacheAttribute)
        {
            var clientType        = svcCacheAttribute.ClientType;
            var redisCacheService = clientType.RedisCacheServiceFactory();

            return(redisCacheService);
        }
        public void CacheKeyManage(IInvocation invocation, ParameterInfo[] parameters, ServiceCacheAttribute svcCacheAttribute)
        {
            var parameterString = GenerateParameterKey(invocation, parameters);
            var cacheKey        = GenerateCacheKey(invocation, parameterString);

            var redisCacheService = RedisCacheServiceFactory(svcCacheAttribute);

            GetDataByCacheKey(invocation, redisCacheService, parameters, svcCacheAttribute, cacheKey);
        }
        private bool CheckCacheKeyLock(IInvocation invocation, IRedisCacheService redisCacheService, ParameterInfo[] parameters, ServiceCacheAttribute svcCacheAttribute, string cacheKey)
        {
            var cacheKeyLocked = string.Format("{0}:LOCK", cacheKey);

            if (redisCacheService.SetNX(cacheKeyLocked))
            {
                try
                {
                    AddCacheKey(invocation, redisCacheService, parameters, svcCacheAttribute, cacheKey);
                }
                catch (Exception ex)
                {
                    LogHelper.Error(string.Format("{0}\r\n{1}", ex.Message, ex.StackTrace.ToString()));
                }
                finally
                {
                    redisCacheService.Remove(cacheKeyLocked);
                }

                return(false);
            }
            return(true);
        }
        private void GetDataByCacheKey(IInvocation invocation, IRedisCacheService redisCacheService, ParameterInfo[] parameters, ServiceCacheAttribute svcCacheAttribute, string cacheKey)
        {
            int retryTimes = 0;

            if (redisCacheService.Contains(cacheKey))
            {
                GetDataByCacheKey(invocation, redisCacheService, parameters, cacheKey);
                retryTimes = 0;
            }
            else
            {
Label_RETRY:
                var isLock = CheckCacheKeyLock(invocation, redisCacheService, parameters, svcCacheAttribute, cacheKey);
                if (isLock)
                {
                    while (retryTimes <= 3)
                    {
                        Thread.Sleep(500);
                        retryTimes++;
                        goto Label_RETRY;
                    }
                    var cacheKeyLocked = string.Format("{0}:LOCK", cacheKey);
                    redisCacheService.Remove(cacheKeyLocked);
                }
            }
        }
 private bool CheckCacheKey(IInvocation invocation, IRedisCacheService redisCacheService, ParameterInfo[] parameters, ServiceCacheAttribute svcCacheAttribute, string cacheKey)
 {
     if (redisCacheService.Contains(cacheKey))
     {
         GetDataByCacheKey(invocation, redisCacheService, parameters, cacheKey);
         return(false);
     }
     else
     {
         CheckCacheKeyLock(invocation, redisCacheService, parameters, svcCacheAttribute, cacheKey);
         return(true);
     }
 }
        private void AddCacheKey(IInvocation invocation, IRedisCacheService redisCacheService, ParameterInfo[] parameters, ServiceCacheAttribute svcCacheAttribute, string cacheKey)
        {
            invocation.Proceed();

            redisCacheService.AddNullableData(cacheKey, invocation.ReturnValue, svcCacheAttribute.TimeoutSecs);

            for (int i = 0; i < parameters.Length; i++)
            {
                if (parameters[i].ParameterType.IsByRef && invocation.Arguments[i] != null)
                {
                    redisCacheService.Add(cacheKey + parameters[i].Name, invocation.Arguments[i], svcCacheAttribute.TimeoutSecs);
                }
            }
        }