Beispiel #1
0
        public void TestTaskHelper()
        {
            TaskHelper.GetUnderlyingType(typeof(Task <int>), out bool isTask).ShouldBe(typeof(int));
            isTask.ShouldBe(true);

            TaskHelper.GetUnderlyingType(typeof(Task), out isTask).ShouldBe(null);
            isTask.ShouldBe(true);

            TaskHelper.GetUnderlyingType(typeof(int), out isTask).ShouldBe(typeof(int));
            isTask.ShouldBe(false);

            TaskHelper.ConvertToGeneric(typeof(int), Task.FromResult <object>(1)).ShouldBeAssignableTo(typeof(Task <int>));

            TaskHelper.GetResult(Task.FromResult(1)).ShouldBe(1);
            TaskHelper.GetResult(Task.CompletedTask).ShouldBe(null);
        }
Beispiel #2
0
        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) ??
        }