Example #1
0
        public async Task <string> GetServerAsync(string serviceName)
        {
            var cached = await _provider.GetAsync(serviceName, async() =>
            {
                var serviceInstances = await _client.ListInstancesAsync(new ListInstancesRequest
                {
                    ServiceName = serviceName,
                    HealthyOnly = true,
                });

                var baseUrl = string.Empty;

                if (serviceInstances != null && serviceInstances.Hosts != null && serviceInstances.Hosts.Any())
                {
                    var list = serviceInstances.Hosts.Select(x => new NacosServer
                    {
                        // it seems that nacos don't return the scheme
                        // so here use http only.
                        Url = $"http://{x.Ip}:{x.Port}"
                    }).ToList();

                    return(list);
                }

                return(null);
            }, TimeSpan.FromSeconds(10));

            if (cached.HasValue)
            {
                var list  = cached.Value;
                var index = new Random().Next(0, list.Count);
                return(list[index].Url);
            }
            else
            {
                return(null);
            }
        }
Example #2
0
        private async Task <List <Host> > GetServerListInnerAsync(string serviceName, string groupName, string clusters, string namespaceId)
        {
            var cachedKey = $"{serviceName}-{groupName}-{clusters}-{namespaceId}";

            var cached = await _provider.GetAsync(cachedKey, async() =>
            {
                var serviceInstances = await _client.ListInstancesAsync(new ListInstancesRequest
                {
                    ServiceName = serviceName,
                    GroupName   = groupName,
                    Clusters    = clusters,
                    NamespaceId = namespaceId,
                    HealthyOnly = true,
                }).ConfigureAwait(false);

                if (serviceInstances?.Hosts == null || !serviceInstances.Hosts.Any())
                {
                    return(null);
                }
                return(serviceInstances.Hosts.ToList());
            }, TimeSpan.FromSeconds(8)).ConfigureAwait(false);

            return(cached.HasValue ? cached.Value : null);
        }
        public async Task <T> GetAsync <T>(string key, Func <Task <T> > func, TimeSpan?expiration = null)
        {
            var result = await _provider.GetAsync(key, func, GetExpiration(expiration));

            return(result.Value);
        }
Example #4
0
        /// <summary>
        /// Proceeds the able.
        /// </summary>
        /// <param name="invocation">Invocation.</param>
        private void ProceedAble(IInvocation invocation)
        {
            var serviceMethod = invocation.Method ?? invocation.MethodInvocationTarget;

            if (GetMethodAttributes(serviceMethod).FirstOrDefault(x => x.GetType() == typeof(EasyCachingAbleAttribute)) is EasyCachingAbleAttribute attribute)
            {
                var returnType = serviceMethod.IsReturnTask()
                        ? serviceMethod.ReturnType.GetGenericArguments().First()
                        : serviceMethod.ReturnType;

                var cacheKey = _keyGenerator.GetCacheKey(serviceMethod, invocation.Arguments, attribute.CacheKeyPrefix);

                object cacheValue  = null;
                var    isAvailable = true;
                try
                {
                    cacheValue = (_cacheProvider.GetAsync(cacheKey, returnType)).GetAwaiter().GetResult();
                }
                catch (Exception ex)
                {
                    if (!attribute.IsHightAvailability)
                    {
                        throw;
                    }
                    else
                    {
                        isAvailable = false;
                        _logger?.LogError(new EventId(), ex, $"Cache provider \"{_cacheProvider.Name}\" get error.");
                    }
                }

                if (cacheValue != null)
                {
                    if (serviceMethod.IsReturnTask())
                    {
                        invocation.ReturnValue =
                            TypeofTaskResultMethod.GetOrAdd(returnType, t => typeof(Task).GetMethods().First(p => p.Name == "FromResult" && p.ContainsGenericParameters).MakeGenericMethod(returnType)).Invoke(null, new object[] { cacheValue });
                    }
                    else
                    {
                        invocation.ReturnValue = cacheValue;
                    }
                }
                else
                {
                    // Invoke the method if we don't have a cache hit
                    invocation.Proceed();

                    if (!string.IsNullOrWhiteSpace(cacheKey) && invocation.ReturnValue != null && isAvailable)
                    {
                        if (serviceMethod.IsReturnTask())
                        {
                            //get the result
                            var returnValue = invocation.UnwrapAsyncReturnValue().Result;

                            _cacheProvider.Set(cacheKey, returnValue, TimeSpan.FromSeconds(attribute.Expiration));
                        }
                        else
                        {
                            _cacheProvider.Set(cacheKey, invocation.ReturnValue, TimeSpan.FromSeconds(attribute.Expiration));
                        }
                    }
                }
            }
            else
            {
                // Invoke the method if we don't have EasyCachingAbleAttribute
                invocation.Proceed();
            }
        }
Example #5
0
 public async Task Get_Cached_Value_Async_Should_Throw_ArgumentNullException_When_CacheKey_IsNullOrWhiteSpace(string cachekey)
 {
     await Assert.ThrowsAsync <ArgumentNullException>(async() => await _provider.GetAsync <string>(cachekey, null, _defaultTs));
 }
Example #6
0
 public async Task <TCachedObject> Get <TCachedObject>(string key) =>
 (await _provider.GetAsync <TCachedObject>(key)).Value;
Example #7
0
        public async Task <CacheValue <string> > Consume(string key)
        {
            var item = await _provider.GetAsync <string>(key);

            return(item);
        }
        private async Task <string> PresignedObjectAsync(string bucketName, string objectName, int expiresInt, PresignedObjectType type)
        {
            if (string.IsNullOrEmpty(bucketName))
            {
                throw new ArgumentNullException(nameof(bucketName));
            }
            if (string.IsNullOrEmpty(objectName))
            {
                throw new ArgumentNullException(nameof(objectName));
            }
            if (expiresInt <= 0)
            {
                throw new Exception("ExpiresIn time can not less than 0.");
            }
            if (expiresInt > 7 * 24 * 3600)
            {
                throw new Exception("ExpiresIn time no more than 7 days.");
            }
            long      nowTime       = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
            const int minExpiresInt = 600;
            string    key           = Encrypt.MD5($"{bucketName}_{objectName}_{type.ToString().ToUpper()}");
            string    objectUrl     = null;

            //查找缓存
            if (Options.IsEnableCache && (expiresInt > minExpiresInt))
            {
                var cacheResult = await _cache.GetAsync <PresignedUrlCache>(key);

                PresignedUrlCache cache = cacheResult.HasValue ? cacheResult.Value : null;
                //缓存中存在,且有效时间不低于10分钟
                if (cache != null &&
                    cache.Type == type &&
                    cache.CreateTime > 0 &&
                    (cache.CreateTime + expiresInt - nowTime) > minExpiresInt &&
                    cache.Name == objectName &&
                    cache.BucketName == bucketName)
                {
                    return(cache.Url);
                }
            }
            if (type == PresignedObjectType.Get)
            {
                //生成URL
                AccessMode accessMode = await this.GetObjectAclAsync(bucketName, objectName);

                if (accessMode == AccessMode.PublicRead || accessMode == AccessMode.PublicReadWrite)
                {
                    string bucketUrl = await this.GetBucketEndpointAsync(bucketName);

                    objectUrl = $"{bucketUrl}{(objectName.StartsWith("/") ? "" : "/")}{objectName}";
                }
                else
                {
                    var req = new GeneratePresignedUriRequest(bucketName, objectName, SignHttpMethod.Get)
                    {
                        Expiration = DateTime.Now.AddSeconds(expiresInt)
                    };
                    var uri = _client.GeneratePresignedUri(req);
                    if (uri != null)
                    {
                        objectUrl = uri.ToString();
                    }
                }
            }
            else
            {
                var req = new GeneratePresignedUriRequest(bucketName, objectName, SignHttpMethod.Put)
                {
                    Expiration = DateTime.Now.AddSeconds(expiresInt)
                };
                var uri = _client.GeneratePresignedUri(req);
                if (uri != null)
                {
                    objectUrl = uri.ToString();
                }
            }
            if (string.IsNullOrEmpty(objectUrl))
            {
                throw new Exception("Presigned get object url failed.");
            }
            //save cache
            if (Options.IsEnableCache && expiresInt > minExpiresInt)
            {
                PresignedUrlCache urlCache = new PresignedUrlCache()
                {
                    Url        = objectUrl,
                    CreateTime = nowTime,
                    Name       = objectName,
                    BucketName = bucketName,
                    Type       = type
                };
                int randomSec = new Random().Next(5, 30);
                await _cache.SetAsync(key, urlCache, TimeSpan.FromSeconds(expiresInt + randomSec));
            }
            return(objectUrl);
        }
Example #9
0
 /// <summary>
 /// Gets the specified cacheKey, dataRetriever and expiration async.
 /// </summary>
 /// <typeparam name="T">Type of cache value</typeparam>
 /// <param name="cacheKey">Cache key</param>
 /// <param name="cancellationToken">cancellationToken</param>
 /// <returns>Cached value</returns>
 public async Task <T> GetAsync <T>(string cacheKey, CancellationToken cancellationToken = default)
 {
     return((await _easyCachingProvider.GetAsync <T>(cacheKey).ConfigureAwait(false)).Value);
 }
Example #10
0
        public async Task <T> GetAsync <T>(string key, CancellationToken token)
        {
            var cacheItem = await _provider.GetAsync <T>(KeyPrefix + key);

            return(cacheItem.Value);
        }
        private async Task <string> PresignedObjectAsync(string bucketName, string objectName, int expiresInt, PresignedObjectType type)
        {
            if (string.IsNullOrEmpty(bucketName))
            {
                throw new ArgumentNullException(nameof(bucketName));
            }
            if (string.IsNullOrEmpty(objectName))
            {
                throw new ArgumentNullException(nameof(objectName));
            }
            if (expiresInt <= 0)
            {
                throw new Exception("ExpiresIn time can not less than 0.");
            }
            if (expiresInt > 7 * 24 * 3600)
            {
                throw new Exception("ExpiresIn time no more than 7 days.");
            }
            long               nowTime            = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
            const int          minExpiresInt      = 600;
            string             key                = Encrypt.MD5($"{bucketName}_{objectName}_{type.ToString().ToUpper()}");
            string             objectUrl          = null;
            string             newBucketName      = ConvertBucketName(bucketName);
            PreSignatureStruct preSignatureStruct = new PreSignatureStruct()
            {
                appid              = Options.Endpoint,
                region             = Options.Region,
                bucket             = newBucketName,
                key                = objectName,
                httpMethod         = type.ToString().ToUpper(),
                isHttps            = Options.IsEnableHttps,
                signDurationSecond = expiresInt,
                headers            = null,
                queryParameters    = null,
            };

            //查找缓存
            if (Options.IsEnableCache && (expiresInt > minExpiresInt))
            {
                var cacheResult = await _cache.GetAsync <PresignedUrlCache>(key);

                PresignedUrlCache cache = cacheResult.HasValue ? cacheResult.Value : null;
                //缓存中存在,且有效时间不低于10分钟
                if (cache != null &&
                    cache.Type == type &&
                    cache.CreateTime > 0 &&
                    (cache.CreateTime + expiresInt - nowTime) > minExpiresInt &&
                    cache.Name == objectName &&
                    cache.BucketName == bucketName)
                {
                    return(cache.Url);
                }
            }
            if (type == PresignedObjectType.Get)
            {
                //生成URL
                AccessMode accessMode = await this.GetObjectAclAsync(bucketName, objectName);

                if (accessMode == AccessMode.PublicRead || accessMode == AccessMode.PublicReadWrite)
                {
                    objectUrl = $"{(Options.IsEnableHttps ? "https" : "http")}://{newBucketName}.cos.{Options.Region}.myqcloud.com{(objectName.StartsWith("/") ? "" : "/")}{objectName}";
                }
                else
                {
                    string uri = _client.GenerateSignURL(preSignatureStruct);
                    if (uri != null)
                    {
                        objectUrl = uri.ToString();
                    }
                }
            }
            else
            {
                string uri = _client.GenerateSignURL(preSignatureStruct);
                if (uri != null)
                {
                    objectUrl = uri.ToString();
                }
            }
            if (string.IsNullOrEmpty(objectUrl))
            {
                throw new Exception("Presigned get object url failed.");
            }
            //save cache
            if (Options.IsEnableCache && expiresInt > minExpiresInt)
            {
                PresignedUrlCache urlCache = new PresignedUrlCache()
                {
                    Url        = objectUrl,
                    CreateTime = nowTime,
                    Name       = objectName,
                    BucketName = bucketName,
                    Type       = type
                };
                int randomSec = new Random().Next(5, 30);
                await _cache.SetAsync(key, urlCache, TimeSpan.FromSeconds(expiresInt + randomSec));
            }
            return(objectUrl);
        }
Example #12
0
        public async Task <T> Get <T>(string key)
        {
            var res = await _provider.GetAsync <T>(key);

            return(res.Value);
        }
Example #13
0
        /// <summary>
        /// Proceeds the able async.
        /// </summary>
        /// <returns>The able async.</returns>
        /// <param name="context">Context.</param>
        /// <param name="next">Next.</param>
        private async Task ProceedAbleAsync(AspectContext context, AspectDelegate next)
        {
            if (GetMethodAttributes(context.ServiceMethod).FirstOrDefault(x => x.GetType() == typeof(EasyCachingAbleAttribute)) is EasyCachingAbleAttribute attribute)
            {
                var returnType = context.IsAsync()
                        ? context.ServiceMethod.ReturnType.GetGenericArguments().First()
                        : context.ServiceMethod.ReturnType;

                var cacheKey = KeyGenerator.GetCacheKey(context.ServiceMethod, context.Parameters, attribute.CacheKeyPrefix);

                object cacheValue  = null;
                var    isAvailable = true;
                try
                {
                    cacheValue = await _cacheProvider.GetAsync(cacheKey, returnType);
                }
                catch (Exception ex)
                {
                    if (!attribute.IsHightAvailability)
                    {
                        throw;
                    }
                    else
                    {
                        isAvailable = false;
                        Logger?.LogError(new EventId(), ex, $"Cache provider \"{_cacheProvider.Name}\" get error.");
                    }
                }

                if (cacheValue != null)
                {
                    if (context.IsAsync())
                    {
                        //#1
                        //dynamic member = context.ServiceMethod.ReturnType.GetMember("Result")[0];
                        //dynamic temp = System.Convert.ChangeType(cacheValue.Value, member.PropertyType);
                        //context.ReturnValue = System.Convert.ChangeType(Task.FromResult(temp), context.ServiceMethod.ReturnType);

                        //#2
                        context.ReturnValue =
                            TypeofTaskResultMethod.GetOrAdd(returnType, t => typeof(Task).GetMethods().First(p => p.Name == "FromResult" && p.ContainsGenericParameters).MakeGenericMethod(returnType)).Invoke(null, new object[] { cacheValue });
                    }
                    else
                    {
                        //context.ReturnValue = System.Convert.ChangeType(cacheValue.Value, context.ServiceMethod.ReturnType);
                        context.ReturnValue = cacheValue;
                    }
                }
                else
                {
                    // Invoke the method if we don't have a cache hit
                    await next(context);

                    if (isAvailable)
                    {
                        if (context.IsAsync())
                        {
                            //get the result
                            var returnValue = await context.UnwrapAsyncReturnValue();

                            await _cacheProvider.SetAsync(cacheKey, returnValue, TimeSpan.FromSeconds(attribute.Expiration));
                        }
                        else
                        {
                            await _cacheProvider.SetAsync(cacheKey, context.ReturnValue, TimeSpan.FromSeconds(attribute.Expiration));
                        }
                    }
                }
            }
            else
            {
                // Invoke the method if we don't have EasyCachingAbleAttribute
                await next(context);
            }
        }