/// <summary> /// <para> Builds a <see cref="Policy"/> that will function like a Circuit Breaker.</para> /// <para>The circuit will break after <paramref name="exceptionsAllowedBeforeBreaking"/> /// exceptions that are handled by this policy are raised. The circuit will stay /// broken for the <paramref name="durationOfBreak"/>. Any attempt to execute this policy /// while the circuit is broken, will immediately throw a <see cref="BrokenCircuitException"/> containing the exception /// that broke the cicuit. /// </para> /// <para>If the first action after the break duration period results in an exception, the circuit will break /// again for another <paramref name="durationOfBreak"/>, otherwise it will reset. /// </para> /// </summary> /// <param name="policyBuilder">The policy builder.</param> /// <param name="exceptionsAllowedBeforeBreaking">The number of exceptions that are allowed before opening the circuit.</param> /// <param name="durationOfBreak">The duration the circuit will stay open before resetting.</param> /// <returns>The policy instance.</returns> /// <remarks>(see "Release It!" by Michael T. Nygard fi)</remarks> /// <exception cref="System.ArgumentOutOfRangeException">exceptionsAllowedBeforeBreaking;Value must be greater than zero.</exception> public static Policy CircuitBreaker(this PolicyBuilder policyBuilder, int exceptionsAllowedBeforeBreaking, TimeSpan durationOfBreak) { if (exceptionsAllowedBeforeBreaking <= 0) { throw new ArgumentOutOfRangeException("exceptionsAllowedBeforeBreaking", "Value must be greater than zero."); } var policyState = new CircuitBreakerState(exceptionsAllowedBeforeBreaking, durationOfBreak); return(new Policy(action => CircuitBreakerPolicy.Implementation(action, policyBuilder.ExceptionPredicates, policyState))); }
/// <summary> /// <para>Builds the policy that will "break the circuit" after <paramref name="countBeforeBreaking"/> /// exceptions that could be handled by the <paramref name="syntax"/> being built. The circuit /// stays broken for the <paramref name="duration"/>. Any attempt to /// invoke method within the policy, while the circuit is broken, will immediately re-throw /// the last exception. </para> /// <para>If the action fails within the policy after the block period, then the breaker /// is blocked again for the next <paramref name="duration"/>. /// It will be reset, otherwise.</para> /// </summary> /// <param name="syntax">The syntax.</param> /// <param name="duration">How much time the breaker will stay open before resetting</param> /// <param name="countBeforeBreaking">How many exceptions are needed to break the circuit</param> /// <returns>shared policy instance</returns> /// <remarks>(see "ReleaseIT!" for the details)</remarks> public static ActionPolicyWithState CircuitBreaker(this Syntax <ExceptionHandler> syntax, TimeSpan duration, int countBeforeBreaking) { Enforce.Argument(() => syntax); Enforce.Argument(() => countBeforeBreaking, Is.GreaterThan(0)); Enforce.Argument(() => duration, Is.NotDefault); var state = new CircuitBreakerState(duration, countBeforeBreaking); var syncLock = new CircuitBreakerStateLock(state); return(new ActionPolicyWithState(action => CircuitBreakerPolicy.Implementation(action, syntax.Target, syncLock))); }