private void ChangeState(CircuitBreakerState state)
 {
     this.State = state;
     this.OnCircuitBreakerStateChanged(new EventArgs()
     {
     });
 }
        public CircuitBreaker(int threshold, int openCircuitTimeoutInMilliseconds, IList <Type> ignoredExceptionTypes)
        {
            if (threshold <= 0)
            {
                throw new ArgumentOutOfRangeException("threshold", threshold, "The threshold must be greater than 0.");
            }

            if (openCircuitTimeoutInMilliseconds < 1)
            {
                throw new ArgumentOutOfRangeException("openCircuitTimeoutInMilliseconds", openCircuitTimeoutInMilliseconds, "The timeout of an open circuit should be greater than 1 millisecond.");
            }

            if (ignoredExceptionTypes == null)
            {
                throw new ArgumentNullException("ignoredExceptionTypes", "The list of ignored exception type should not be null.");
            }

            this.disposed              = false;
            this.threshold             = threshold;
            this.failureCount          = 0;
            this.state                 = CircuitBreakerState.Closed;
            this.ignoredExceptionTypes = ignoredExceptionTypes;

            this.openCircuitTimer          = new Timer(openCircuitTimeoutInMilliseconds);
            this.openCircuitTimer.Elapsed += this.OpenCircuitTimerElapsed;
        }
 public void ChangeState(CircuitBreakerState state)
 {
     State = state;
     OnCircuitBreakerStateChanged(new EventArgs()
     {
     });
 }
        public async Task Trip(Exception exception)
        {
            if (ShouldTripCircuitBreaker(exception) == false)
            {
                return;
            }

            var timeStamp = rebusTime.Now;

            _errorDates.TryAdd(timeStamp.Ticks, timeStamp);

            var errorsInPeriod = _errorDates
                                 .Where(x => x.Key > timeStamp.Ticks - settings.TrackingPeriod.Ticks)
                                 .Take(settings.Attempts)
                                 .ToList();

            var numberOfErrorsInPeriod = errorsInPeriod.Count;

            if (IsInRecoveringState(numberOfErrorsInPeriod))
            {
                State = CircuitBreakerState.Open;
                return;
            }

            // Do the tripping
            if (numberOfErrorsInPeriod >= settings.Attempts)
            {
                State = CircuitBreakerState.Open;
            }

            RemoveOutOfPeriodErrors(errorsInPeriod);

            await Task.FromResult(0);
        }
        public async Task Reset()
        {
            if (IsClosed)
            {
                return;
            }

            var latestError = _errorDates
                              .OrderBy(x => x.Key)
                              .Take(1)
                              .FirstOrDefault();

            if (latestError.Equals(default(KeyValuePair <int, DateTimeOffset>)))
            {
                return;
            }

            var currentTime = rebusTime.Now;

            if (currentTime > latestError.Value + settings.HalfOpenResetInterval)
            {
                State = CircuitBreakerState.HalfOpen;
            }

            if (currentTime > latestError.Value + settings.CloseResetInterval)
            {
                State = CircuitBreakerState.Closed;
            }
        }
Beispiel #6
0
        private static async Task <CircuitBreakerState> RunScenario(int[] openingRates, Rating[] analyseResponses)
        {
            var circuitBreakerPeriod = new CircuitBreakerPeriod {
                PeriodMs = 10
            };
            var circuitBreakerOpeningRates = A.Fake <ICircuitBreakerOpeningRates>();
            var circuitBreakerAnalyser     = new StubCircuitBreakerAnalyser(analyseResponses);
            var testSubject = new CircuitBreakerState("policy", circuitBreakerAnalyser, circuitBreakerOpeningRates, circuitBreakerPeriod);

            A.CallTo(() => circuitBreakerOpeningRates.OpeningRates).Returns(openingRates);

            var monitorTask = Task.Run(() => testSubject.MonitorAsync(CancellationToken.None));

            // Wait long enough for the monitor task to throw an exception, due to no more analyser responses
            await Task.Delay(100);

            try
            {
                await monitorTask;
            }
            catch (InvalidOperationException)
            {
            }

            return(testSubject);
        }
Beispiel #7
0
        public void when_a_circuitbreaker_exists_then_setting_forces_the_state_to_be_that_of_the_message(
            [Values(CircuitBreakerStatus.Open, CircuitBreakerStatus.HalfOpen, CircuitBreakerStatus.Closed, CircuitBreakerStatus.ForcedClosed, CircuitBreakerStatus.ForcedOpen)]
            CircuitBreakerStatus startingState,

            [Values(CircuitBreakerStatus.Open, CircuitBreakerStatus.HalfOpen, CircuitBreakerStatus.Closed, CircuitBreakerStatus.ForcedClosed, CircuitBreakerStatus.ForcedOpen)]
            CircuitBreakerStatus desiredState)
        {
            CircuitBreakerState state = Helper.MakeBreakerState(1, startingState);

            CircuitBreakerState originalState = _set.ProcessCircuitStateMessage(state);

            CircuitBreakerState result = _set.SetCircuitState(originalState.CircuitBreakerId, desiredState, SystemTime.Now());

            CircuitBreakerState fetchedState = _set.TryGetCircuit(originalState.CircuitBreakerId);

            Assert.That(result, Is.Not.Null);
            Assert.That(result.Status, Is.EqualTo(desiredState));
            Assert.That(result.MessageSequenceNumber, Is.EqualTo(originalState.MessageSequenceNumber)); // important that the sequence number does not change -> otherwise the next inbound messages will be discards by the dashboard.


            Assert.That(fetchedState, Is.Not.Null);
            Assert.That(fetchedState.Status, Is.EqualTo(desiredState));
            Assert.That(fetchedState.MessageSequenceNumber, Is.EqualTo(originalState.MessageSequenceNumber));
            Assert.That(_set.Circuits(), Contains.Item(originalState.CircuitBreakerId));
        }
Beispiel #8
0
        public static string UpdateSpecificCircuit(CircuitBreakerSet set, string circuitId, int sequenceNumber)
        {
            CircuitBreakerState input = MakeBreakerState(messageSequenceNumber: sequenceNumber, id: circuitId);

            set.ProcessCircuitStateMessage(input);
            return(circuitId);
        }
 private void ResetCircuitBreaker()
 {
     lock (padLock)
     {
         _state = CircuitBreakerState.Closed;
     }
 }
        public void circuit_should_be_accepting_all_requests_on_creation()
        {
            var testSubject = new CircuitBreakerState("policy", A.Fake <ICircuitBreakerAnalyser>(), A.Fake <ICircuitBreakerOpeningRates>(), A.Fake <ICircuitBreakerPeriod>());

            var accepts = Enumerable.Range(0, 100).Select(c => testSubject.ShouldAccept()).ToArray();

            Assert.That(accepts.All(c => c), Is.True);
        }
Beispiel #11
0
        public static string AddRandomCircuit(CircuitBreakerSet set)
        {
            CircuitBreakerState input = MakeBreakerState(messageSequenceNumber: 15);
            var circuitId             = input.CircuitBreakerId;

            set.ProcessCircuitStateMessage(input);
            return(circuitId);
        }
        /// <summary>
        /// Handles state change logic.
        /// </summary>
        /// <param name="newState"></param>
        private void ChangeState(CircuitBreakerState newState)
        {
            // Change the circuit breaker state
            this.state = newState;

            // Raise changed event
            this.OnCircuitBreakerStateChanged(new EventArgs());
        }
Beispiel #13
0
        public async Task <CircuitBreakerState> GetStateAsync(string serviceName, string functionName)
        {
            var table = _cloudStorageAccount.CreateCloudTableClient().GetTableReference(TABLE_STATE);

            CircuitBreakerFunctionState functionState = (await table.ExecuteAsync(TableOperation.Retrieve <CircuitBreakerFunctionState>(serviceName, functionName))).Result as CircuitBreakerFunctionState;

            return(functionState == null ? null : CircuitBreakerState.FromState(functionState));
        }
Beispiel #14
0
        public CircuitBreaker(uint threshold, TimeSpan resetTimeout)
        {
            this._threshold = threshold;
            _failureCount   = 0;
            _state          = CircuitBreakerState.Closed;

            _resetTimer          = new Timer(resetTimeout.TotalMilliseconds);
            _resetTimer.Elapsed += ResetTimerElapsed;
        }
Beispiel #15
0
        public void when_a_circuitbreaker_does_not_exist_then_setting_a_state_returns_null()
        {
            // the rationale behind this logic is that the circuit has been garbage collected because it was offline long enough.
            // therefore a 'set' command from the UI should not create it, but ignore it. A null is returned rather than an exception.

            CircuitBreakerState result = _set.SetCircuitState(Guid.NewGuid().ToString("N"), CircuitBreakerStatus.HalfOpen, SystemTime.Now());

            Assert.That(result, Is.Null);
            Assert.That(_set.Circuits(), Is.Not.Contains("a"));
        }
        public CircuitBreaker(uint threshold, uint timeout)
        {
            this.threshold             = threshold;
            this.failureCount          = 0;
            this.state                 = CircuitBreakerState.Closed;
            this.ignoredExceptionTypes = new List <Type>();

            this.timer          = new System.Timers.Timer(timeout);
            this.timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
        }
        public CircuitBreaker(uint threshold, uint timeout)
        {
            this.threshold = threshold;
            this.failureCount = 0;
            this.state = CircuitBreakerState.Closed;
            this.ignoredExceptionTypes = new List<Type>();

            this.timer = new System.Timers.Timer(timeout);
            this.timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
        }
 private void ProcessException(Exception ex)
 {
     lock (padLock)
     {
         lastFailureTime = DateTime.Now;
         lastException   = ex;
         _state          = CircuitBreakerState.Open;
     }
     throw new CircuitBreakerOpenException(lastException);
 }
        public CircuitBreaker(int threshold, int timeout)
        {
            _threshold             = threshold;
            _failureCount          = 0;
            _state                 = CircuitBreakerState.Closed;
            _ignoredExceptionTypes = new List <Type>();

            _timer          = new Timer(timeout);
            _timer.Elapsed += TimerElapsed;
        }
Beispiel #20
0
        /// <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)));
        }
Beispiel #21
0
        /// <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)));
        }
        /// <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 CircuitBreakerAsync(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, cancellationToken, continueOnCapturedContext) => CircuitBreakerPolicy.ImplementationAsync(action, cancellationToken, policyBuilder.ExceptionPredicates, policyState, continueOnCapturedContext),
                       policyBuilder.ExceptionPredicates
                       ));
        }
        public void adding_an_unseen_circuit_returns_a_passthrough_message_stamped_with_current_time()
        {
            SystemTime.Is(millisecond: 100);
            CircuitBreakerState input = Helper.MakeBreakerState(messageSequenceNumber: 15);

            SystemTime.Is(millisecond: 200);
            CircuitBreakerState result = _set.ProcessCircuitStateMessage(input);


            Assert.That(result.CircuitBreakerId, Is.EqualTo(input.CircuitBreakerId), "CircuitBreakerId");
            Assert.That(result.MessageSequenceNumber, Is.EqualTo(input.MessageSequenceNumber), "RequestMessageSequenceNumber");
            Assert.That(result.ProcessId, Is.EqualTo(input.ProcessId), "ProcessID");
            Assert.That(result.Status, Is.EqualTo(input.Status), "Status");
            Assert.That(result.MachineName, Is.EqualTo(input.MachineName), "MachineName");
            Assert.That(result.LastModifiedDate, Is.EqualTo(input.LastModifiedDate.AddMilliseconds(100)), "LastModifiedDate");
            Assert.That(result.LastModifiedDate, Is.EqualTo(SystemTime.Now()), "LastModifiedDate should be now");
        }
        public void an_older_message_for_existing_breaker_is_ignored_by_update_and_returns_the_more_recent_state()
        {
            SystemTime.Is(second: 1, millisecond: 100);

            CircuitBreakerState original       = Helper.MakeBreakerState("a", messageSequenceNumber: 15);
            CircuitBreakerState originalResult = _set.ProcessCircuitStateMessage(original);
            CircuitBreakerState ignoredResult  =
                _set.ProcessCircuitStateMessage(Helper.MakeBreakerState("a", messageSequenceNumber: 14));


            Assert.That(ignoredResult.CircuitBreakerId, Is.EqualTo(originalResult.CircuitBreakerId), "CircuitBreakerId");
            Assert.That(ignoredResult.MessageSequenceNumber, Is.EqualTo(originalResult.MessageSequenceNumber), "RequestMessageSequenceNumber");
            Assert.That(ignoredResult.ProcessId, Is.EqualTo(originalResult.ProcessId), "ProcessID");
            Assert.That(ignoredResult.Status, Is.EqualTo(originalResult.Status), "Status");
            Assert.That(ignoredResult.MachineName, Is.EqualTo(originalResult.MachineName), "MachineName");
            Assert.That(ignoredResult.LastModifiedDate, Is.EqualTo(SystemTime.Now()), "LastModifiedDate should be now");
        }
        public void a_newer_message_number_for_existing_breaker_is_processed_for_update()
        {
            SystemTime.Is(second: 1, millisecond: 100);

            CircuitBreakerState original       = Helper.MakeBreakerState("a", messageSequenceNumber: 15);
            CircuitBreakerState originalResult = _set.ProcessCircuitStateMessage(original);

            SystemTime.Is(second: 2, millisecond: 200);
            CircuitBreakerState newResult =
                _set.ProcessCircuitStateMessage(Helper.MakeBreakerState("a", messageSequenceNumber: 16));


            Assert.That(newResult.CircuitBreakerId, Is.EqualTo(originalResult.CircuitBreakerId), "CircuitBreakerId");
            Assert.That(newResult.MessageSequenceNumber, Is.EqualTo(16), "RequestMessageSequenceNumber");
            Assert.That(newResult.ProcessId, Is.EqualTo(originalResult.ProcessId), "ProcessID");
            Assert.That(newResult.Status, Is.EqualTo(originalResult.Status), "Status");
            Assert.That(newResult.MachineName, Is.EqualTo(originalResult.MachineName), "MachineName");
            Assert.That(newResult.LastModifiedDate, Is.EqualTo(SystemTime.Now()), "LastModifiedDate should be now");
        }
        public CircuitBreakerState Trip(Exception exception, CircuitBreakerState currentState)
        {
            var now     = ticksFn();
            var horizon = now - interval;
            int count;

            lock (wsync)
            {
                errors.Add(now);
                count = errors.CountItems(x => x > horizon);
            }

            if (count > maxErrorsInInterval)
            {
                return(CircuitBreakerState.Open);
            }

            return(count > 0 ? CircuitBreakerState.HalfOpen : CircuitBreakerState.Closed);
        }
        public CircuitBreaker(int threshold = 5, int timeout = 60000)
        {
            if (threshold <= 0)
            {
                throw new ArgumentOutOfRangeException($"{threshold} deve ser maior que zero");
            }

            if (timeout <= 0)
            {
                throw new ArgumentOutOfRangeException($"{timeout} deve ser maior que zero");
            }

            this.ThresHold = threshold;
            this.Timeout   = timeout;
            this.State     = CircuitBreakerState.Closed;

            this.Timer          = new Timer(timeout);
            this.Timer.Enabled  = false;
            this.Timer.Elapsed += Timer_Elapsed;
        }
Beispiel #28
0
        public async Task setup_scenario_base()
        {
            ClosedPcts    = new List <double>();
            ShouldAccepts = new List <bool>();

            var circuitBreakerPeriod = new CircuitBreakerPeriod {
                PeriodMs = 100
            };
            var circuitBreakerOpeningRates = new BinaryCircuitBreakerOpeningRates();
            var circuitBreakerAnalyser     = new DefaultCircuitBreakerAnalyser();

            TestSubject = new CircuitBreakerState("policy", circuitBreakerAnalyser, circuitBreakerOpeningRates, circuitBreakerPeriod);

            var cancellationTokenSource = new CancellationTokenSource();
            var monitorTask             = Task.Run(() => TestSubject.MonitorAsync(cancellationTokenSource.Token));

            await RunScenario();

            cancellationTokenSource.Cancel();
            await monitorTask;
        }
Beispiel #29
0
        void ChangeCircuitBreakerState(CircuitBreakerState previousState, CircuitBreakerState currentState)
        {
            _log.Info("Circuit breaker changed from {PreviousState} to {State}", previousState, currentState);
            _circuitBreakerEvents.RaiseCircuitBreakerChanged(currentState);

            if (currentState == CircuitBreakerState.Closed)
            {
                SetNumberOfWorkers(_configuredNumberOfWorkers);
                return;
            }

            if (currentState == CircuitBreakerState.HalfOpen)
            {
                SetNumberOfWorkers(1);
                return;
            }

            if (currentState == CircuitBreakerState.Open)
            {
                SetNumberOfWorkers(0);
                return;
            }
        }
 public CircuitBreaker()
 {
     _state  = CircuitBreakerState.Closed;
     padLock = new object();
 }
Beispiel #31
0
        public override void Update(float elapsedSeconds)
        {
            SetClosingAuthorization(TCSClosingAuthorization() && DriverClosingAuthorization() && CurrentPantographState() == PantographState.Up);

            switch (CurrentState())
            {
            case CircuitBreakerState.Closed:
                if (!ClosingAuthorization())
                {
                    SetCurrentState(CircuitBreakerState.Open);
                }
                break;

            case CircuitBreakerState.Closing:
                if (ClosingAuthorization() && (DriverClosingOrder() || TCSClosingOrder()))
                {
                    if (!ClosingTimer.Started)
                    {
                        ClosingTimer.Start();
                    }

                    if (ClosingTimer.Triggered)
                    {
                        ClosingTimer.Stop();
                        SetCurrentState(CircuitBreakerState.Closed);
                    }
                }
                else
                {
                    ClosingTimer.Stop();
                    SetCurrentState(CircuitBreakerState.Open);
                }
                break;

            case CircuitBreakerState.Open:
                if (ClosingAuthorization() && (DriverClosingOrder() || TCSClosingOrder()))
                {
                    SetCurrentState(CircuitBreakerState.Closing);
                }
                break;
            }

            if (PreviousState != CurrentState())
            {
                switch (CurrentState())
                {
                case CircuitBreakerState.Open:
                    SignalEvent(Event.CircuitBreakerOpen);
                    break;

                case CircuitBreakerState.Closing:
                    SignalEvent(Event.CircuitBreakerClosing);
                    break;

                case CircuitBreakerState.Closed:
                    SignalEvent(Event.CircuitBreakerClosed);
                    break;
                }
            }

            PreviousState = CurrentState();
        }
        /// <summary>
        /// Handles state change logic.
        /// </summary>
        /// <param name="newState"></param>
        private void ChangeState(CircuitBreakerState newState)
        {
            // Change the circuit breaker state
            this.state = newState;

            // Raise changed event
            this.OnCircuitBreakerStateChanged(new EventArgs());
        }
 private void ResetCircuitBreaker()
 {
     lock (padLock)
     {
         _state = CircuitBreakerState.Closed;
     }
 }
 private void ProcessException(Exception ex)
 {
     lock (padLock)
     {
         lastFailureTime = DateTime.Now;
         lastException = ex;
         _state = CircuitBreakerState.Open;
     }
     throw new CircuitBreakerOpenException(lastException);
 }
 public CircuitBreaker()
 {
     _state = CircuitBreakerState.Closed;
     padLock = new object();
 }