/// <summary>
        /// 将满足中断条件的响应放入缓存
        /// </summary>
        /// <param name="argument"></param>
        /// <param name="result">响应结果</param>
        public void SetFunseResult(RetryPolicyArgument argument, ResponseWrapperResult result)
        {
            //未开启中断配置,或成功响应跳过
            if (argument.Option == null || !argument.Option.FuseEnabled || argument.IsSuccessResponse(result.Response))
            {
                return;
            }

            var       key   = $"{argument.Service}.{argument.Module}";
            FuseEntry entry = default;

            if (_cache.TryGetValue <FuseEntry>(key, out entry))
            {
                if (entry.FailedCount >= argument.Option.FuseEnabledWhenFailedCount)
                {
                    _logger.LogWarning($"服务{key}连续失败次数:{entry.FailedCount}已达阈值:{argument.Option.FuseEnabledWhenFailedCount},触发中断,时间:{argument.Option.FuseDuration}ms");
                    entry.Result       = result;
                    entry.Result.Fused = true;
                }
            }
            else
            {
                entry = new FuseEntry();
            }
            entry.FailedCount++;
            _cache.Set <FuseEntry>(key, entry, TimeSpan.FromMilliseconds(argument.Option.FuseDuration));
        }
Exemplo n.º 2
0
        public ResponseWrapperResult Read(HttpRequest request)
        {
            var result = new ResponseWrapperResult
            {
                Request = request
            };
            var flag = _caching.TryGetValue <HttpResponse>(request.RequestHash, out HttpResponse response);

            if (flag)
            {
                result.HasHitCache = true;
                result.Response    = response;
            }
            return(result);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="argument"></param>
        /// <returns></returns>
        public async Task <ResponseWrapperResult> ProcessAsync(RetryPolicyArgument argument)
        {
            var fusedResult = TryGetFuseResult(argument.Service, argument.Module);

            if (fusedResult != null)
            {
                return(fusedResult);
            }

            var records = new List <RequestRecord>();
            var option  = argument.Option;

            await HandleException(argument.Request, async() =>
            {
                var timeoutToken = (option?.TotalTimeout ?? 0) > 0
                     ? new CancellationTokenSource(TimeSpan.FromMilliseconds(option.TotalTimeout))
                     : new CancellationTokenSource();
                return(await SendWithRetryAsync(option, argument.Request, argument.Sending, records, timeoutToken.Token));
            }, record =>
            {
                //只有执行超时才会抛ExecutionHttpException,意味着重试结束
                if (record.Exception is ExecutionHttpException executionEx)
                {
                    record.Request   = executionEx.Request;
                    record.Exception = executionEx.InnerException;
                    record.Duration  = GetDuration(record.Request.TimeStamp);
                    records.Add(record);
                }
                return(record);
            });

            var result = new ResponseWrapperResult
            {
                Request    = argument.Request,
                Records    = records,
                Duration   = GetDuration(argument.Request.TimeStamp),
                RetryCount = records.Count() > 1 ? records.Count() - 1 : 0
            };
            //获取有效请求记录
            RequestRecord vaildRecord = result.Records.LastOrDefault(x => x.Response != null)
                                        ?? result.Records.LastOrDefault();

            result.Response  = vaildRecord?.Response;
            result.Exception = vaildRecord?.Exception;
            _logger.LogInformation($"请求{argument.Request.RequestUri}执行完毕,用时:{result.Duration}ms");
            SetFunseResult(argument, result);
            return(result);
        }
Exemplo n.º 4
0
 public async Task WriteAsync(RequestDescriptor description, ResponseWrapperResult result)
 {
     await Task.CompletedTask;
 }