/// <summary> /// 异步生成断路器包装策略 /// </summary> /// <typeparam name="TResult">结果类型</typeparam> /// <typeparam name="TException">异常类型</typeparam> /// <param name="options">断路器包装策略选项配置</param> /// <param name="log">日志</param> /// <returns>策略任务</returns> public static IAsyncPolicy <TResult> BuilderBreakerWrapPollicyAsync <TResult, TException>(Action <BreakerWrapPolicyOptions <TResult> > options = null, ILogable log = null) where TException : Exception { var config = new BreakerWrapPolicyOptions <TResult>(); if (options != null) { options(config); } var policys = new List <IAsyncPolicy <TResult> >(); // 降级 var fallback = Policy <TResult> .Handle <TException>().FallbackAsync(token => { return(Task <TResult> .Run(() => { if (config.GetResult == null) { return config.Result; } else { return config.GetResult(); } })); }); policys.Add(fallback); // 断路 if (config.Breaker != null) { var breaker = Policy <TResult> .Handle <TException>() .CircuitBreakerAsync( handledEventsAllowedBeforeBreaking: config.Breaker.HandledEventsAllowedBeforeBreaking, durationOfBreak: TimeSpan.FromSeconds(config.Breaker.DurationOfBreak), onBreak: (ex, state, ts, context) => { log.AvailableLog().WranAsync($"(onBreak)进入断路器,状态:{state},timespan:{ts}", ex.Exception, thisName, tags: config.Id); }, onReset: (context) => { log.AvailableLog().InfoAsync(msg: "(onReset)关闭断路器", source: thisName, tags: config.Id); }, onHalfOpen: () => { log.AvailableLog().InfoAsync(msg: "(onHalfOpen)半打开断路器", source: thisName, tags: config.Id); }); policys.Add(breaker); } // 重试 if (config.RetryNumber != 0) { var retry = Policy <TResult> .Handle <TException>() .RetryAsync(config.RetryNumber, (ex, num) => { log.AvailableLog().WranAsync(msg: $"(retrt)重试第{num}次", ex.Exception, source: thisName, tags: config.Id); }); policys.Add(retry); } // 超时 if (config.Timeout != 0) { var timeout = Policy.TimeoutAsync <TResult>(config.Timeout); policys.Add(timeout); } return(Policy.WrapAsync <TResult>(policys.ToArray())); }