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); });
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; })); }