public CobCommonClientProxy(ICobRequestResolver requestResolver, IServiceRegistration serviceDiscovery, CobServiceDescription desc, ILoggerFactory loggerFactory) { _desc = desc; _requestResolver = requestResolver; _loggerFactory = loggerFactory; _selector = new DefaultServiceSelector(serviceDiscovery, _desc.ServiceName, loggerFactory?.CreateLogger <DefaultServiceSelector>()); }
//public object Execute(Type returnType, CobServiceDescription desc, Func<ServiceInfo, object> action) //{ // var realType = TaskHelper.GetUnderlyingType(returnType, out bool isTask); // var task = Task.Factory.StartNew(() => { // Func<ServiceInfo, object> method = null; // if (isTask) // { // method = s => TaskHelper.GetResult((Task)action(s));//todo:使用token改为异步等待 // } // else // { // method = action; // } // return ExecuteSync(desc, method); // }); // if (isTask) // return TaskHelper.ConvertToGeneric(realType, task); // return task.ConfigureAwait(false).GetAwaiter().GetResult(); //} ////同步执行 //private object ExecuteSync(CobServiceDescription desc, Func<ServiceInfo, object> action) //{ // var sw = new Stopwatch(); // Exception error = null; // object result = null; // //重试 // ServiceInfo service = null; // var runTimes = 0; // while (true) // { // service = _selector.GetOne(); // if (service != null) // { // runTimes++; // sw.Restart(); // try // { // result = action(service); // } // catch (Exception ex) // { // if (desc.RetryTimes > 0 && runTimes < desc.RetryTimes && desc.RetryExceptionTypes != null && desc.RetryExceptionTypes.Length > 0 && desc.RetryExceptionTypes.Contains(ex.GetBaseException().GetType())) // { // //tofo:等待一段时间后再重试,还要避免出现大量重试请求 // continue; // } // error = ex.GetBaseException(); // } // break; // } // _logger.LogError("can not get available service for:{0}", desc.ServiceName); // //todo:无服务可用,降级? // throw new Exception("service select failover"); // } // sw.Stop(); // SetState(service, sw, error); // return result; //} //private void SetState(ServiceInfo target, Stopwatch sw, Exception error = null) //{ // //todo:熔断? //// if (error != null) //// { //// _selector.SetServiceFailed(target); //// } // //todo:设置时间 or 异常 // _selector.SetServiceResponseTime(target, sw.Elapsed); //} #endregion #region 都转为Task执行 /// <summary> /// 包状代理,添加重试、超时等机制 /// </summary> public object Execute(Type returnType, CobServiceDescription desc, Func <ServiceInfo, Task <object> > action, MethodInfo method = null, Dictionary <string, object> parameters = null) { Func <ServiceInfo, Task> asyncAction = action; //wrap timeout task if (desc.Timeout.TotalSeconds > 0) { asyncAction = s => { var taskTimeout = Task.Delay(desc.Timeout.TotalSeconds > 0 ? desc.Timeout : TimeSpan.FromSeconds(_requestOptions.DefaultTimeout));//不为空且大于0的超时时间 var taskOriginal = action(s); var taskWrapped = Task.WhenAny(taskOriginal, taskTimeout).ContinueWith(t => { if (t.Result == taskTimeout && taskOriginal.Status < TaskStatus.Running) { throw new TimeoutException(); } var result = taskOriginal.Result; if (desc.Filters != null) { desc.Filters.ForEach(f => f.OnAfterResponse(method, result)); } return(result); }); return(taskWrapped); }; } return(ExecuteAsync(returnType, desc, asyncAction, method, parameters)); }
private object ExecuteAsync(Type returnType, CobServiceDescription desc, Func <ServiceInfo, Task> action, MethodInfo method = null, Dictionary <string, object> parameters = null) { var retry = new ServiceTaskRetryContainer(_loggerFactory, _selector, desc.RetryTimes, desc.RetryExceptionTypes); var taskResult = retry.RunForResult(action).ContinueWith(t => { foreach (var item in t.Result) { if (item.Service != null) { //set exception,超过阈值后熔断 if (item.Exception != null) { _selector.MarkServiceFailed(item.Service, false); } else if (item.Duration.HasValue) { _selector.MarkServiceHealthy(item.Service, item.Duration.Value); } } } if (t.Result.All(i => i.Exception != null)) { var ex = t.Result.First().Exception.GetInnerException(); //failover //降级 fallback if (desc.FallbackHandler != null) { _logger.LogInformation("使用缺省值处理类返回"); var handler = _fallbackHandlers.GetOrAdd(desc.FallbackHandler, k => Activator.CreateInstance(k) as ICobFallbackHandler); return(handler?.GetValue(new CobFallbackHandlerContext { ReturnType = returnType, Exception = ex, ServiceName = desc.ServiceName, Path = desc.Path, Method = method, Parameters = parameters })); } else if (!string.IsNullOrWhiteSpace(desc.FallbackValue)) { _logger.LogInformation("使用缺省值返回"); return(_scripts.GetOrAdd(desc.FallbackValue, k => CSharpScript.EvaluateAsync(k).ConfigureAwait(false).GetAwaiter().GetResult()));//todo:处理是否为Task } //没有缺省值时,抛出异常 throw ex; } return(t.Result.FirstOrDefault(i => i.Exception == null)?.Result); }); var realType = TaskHelper.GetUnderlyingType(returnType, out bool isTask); //匹配返回的类型 if (isTask) { return(TaskHelper.ConvertToGeneric(realType, taskResult)); } else if (realType != null) { return(taskResult.ConfigureAwait(false).GetAwaiter().GetResult());//todo:在beforeRequest时抛出异常,这里就会一直等待? } return(null);//todo:change to default(T) ?? }
public ICobClientProxy GetProxy(CobServiceDescription desc)//指定post { return(new CobCommonClientProxy(_requestResolver, _serviceDiscovery, desc, _loggerFactory, _requestOptions)); }