예제 #1
0
 private AsyncPolicy <IServiceResult> GetPolicy(string route, Type returnValueType)
 {
     return(Policies.GetOrAdd(route, key =>
     {
         var service = ServiceFactory.Get(route);
         var serviceCircuitBreakerOptions = service.ServiceCircuitBreakerOptions;
         var circuitBreakerEvent = ServiceProvider.GetService <ICircuitBreakerEvent>();
         AsyncPolicy <IServiceResult> policy = Policy <IServiceResult> .Handle <Exception>().FallbackAsync <IServiceResult>(
             async ct =>
         {
             //TODO 如果多次降级,根据路由排除此node
             if (circuitBreakerEvent != null)
             {
                 await circuitBreakerEvent.OnFallback(route, service.ClientMethodInfo);
             }
             if (returnValueType == null)
             {
                 return new ServiceResult(null);
             }
             if (service.ServiceCircuitBreakerOptions.HasInjection)
             {
                 return new ServiceResult(await ScriptInjection.Run(route));
             }
             return new ServiceResult(returnValueType.IsValueType ? Activator.CreateInstance(returnValueType) : default);
         });
예제 #2
0
        private AsyncPolicy <object> GetPolicy(string route, Type returnValueType)
        {
            return(Policies.GetOrAdd(route, (key) =>
            {
                var service = ServiceFactory.Get(route);
                var serviceCircuitBreakerOptions = service.ServiceCircuitBreakerOptions;
                var circuitBreakerEvent = ServiceProvider.GetService <ICircuitBreakerEvent>();
                AsyncPolicy <object> policy = Policy <object> .Handle <Exception>().FallbackAsync(
                    async ct =>
                {
                    if (circuitBreakerEvent != null)
                    {
                        await circuitBreakerEvent.OnFallback(route, service.MethodInfo);
                    }
                    if (returnValueType == null)
                    {
                        return null;
                    }
                    if (service.ServiceCircuitBreakerOptions.HasInjection)
                    {
                        return await ScriptInjection.Run(route);
                    }
                    return returnValueType.IsValueType ? Activator.CreateInstance(returnValueType) : null;
                });
                if (serviceCircuitBreakerOptions.ExceptionsAllowedBeforeBreaking > 0)
                {
                    policy = policy.WrapAsync(Policy.Handle <Exception>().CircuitBreakerAsync(serviceCircuitBreakerOptions.ExceptionsAllowedBeforeBreaking, serviceCircuitBreakerOptions.DurationOfBreak,
                                                                                              async(ex, state, ts, ctx) =>
                    {
                        if (circuitBreakerEvent != null)
                        {
                            await circuitBreakerEvent.OnBreak(route, service.MethodInfo, ex, ts);
                        }
                    },
                                                                                              async ctx =>
                    {
                        if (circuitBreakerEvent != null)
                        {
                            await circuitBreakerEvent.OnRest(route, service.MethodInfo);
                        }
                    },
                                                                                              async() =>
                    {
                        if (circuitBreakerEvent != null)
                        {
                            await circuitBreakerEvent.OnHalfOpen(route, service.MethodInfo);
                        }
                    }));
                }
                if (serviceCircuitBreakerOptions.Retry > 0)
                {
                    policy = policy.WrapAsync(Policy.Handle <Exception>().RetryAsync(serviceCircuitBreakerOptions.Retry,
                                                                                     async(ex, times) =>
                    {
                        if (circuitBreakerEvent != null)
                        {
                            await circuitBreakerEvent.OnRetry(route, service.MethodInfo, ex, times);
                        }
                    }));
                }

                if (serviceCircuitBreakerOptions.Timeout.Ticks > 0)
                {
                    policy = policy.WrapAsync(Policy.TimeoutAsync(serviceCircuitBreakerOptions.Timeout, TimeoutStrategy.Pessimistic,
                                                                  async(ctx, ts, task, ex) =>
                    {
                        if (circuitBreakerEvent != null)
                        {
                            await circuitBreakerEvent.OnTimeOut(route, service.MethodInfo, ex);
                        }
                    }));
                }
                return policy;
            }));
        }