/// <inheritdoc/>
        public HystrixHealthCounts GetHealthCounts()
        {
            // we put an interval between snapshots so high-volume commands don't
            // spend too much unnecessary time calculating metrics in very small time periods
            long lastTime    = lastHealthCountsSnapshot;
            long currentTime = dateTimeProvider.GetCurrentTimeInMilliseconds();

            if (((currentTime - lastTime) >= configurationService.GetMetricsHealthSnapshotIntervalInMilliseconds() || healthCountsSnapshot == null) &&
                Interlocked.CompareExchange(ref lastHealthCountsSnapshot, dateTimeProvider.GetCurrentTimeInMilliseconds(), lastTime) == lastTime)
            {
                // our thread won setting the snapshot time so we will proceed with generating a new snapshot
                // losing threads will continue using the old snapshot
                long success = counter.GetRollingSum(HystrixRollingNumberEvent.Success);
                long failure = counter.GetRollingSum(HystrixRollingNumberEvent.Failure); // fallbacks occur on this
                long timeout = counter.GetRollingSum(HystrixRollingNumberEvent.Timeout); // fallbacks occur on this

                // not used in dotnet version
                long threadPoolRejected = counter.GetRollingSum(HystrixRollingNumberEvent.ThreadPoolRejected);
                long semaphoreRejected  = counter.GetRollingSum(HystrixRollingNumberEvent.SemaphoreRejected);

                long totalCount      = failure + success + timeout + threadPoolRejected + semaphoreRejected;
                long errorCount      = failure + timeout + threadPoolRejected + semaphoreRejected;
                int  errorPercentage = 0;

                if (totalCount > 0)
                {
                    errorPercentage = (int)((double)errorCount / totalCount * 100);
                }

                healthCountsSnapshot = new HystrixHealthCounts(totalCount, errorCount, errorPercentage);
            }

            return(healthCountsSnapshot);
        }
        /// <inheritdoc/>
        private bool IsOpen()
        {
            if (CircuitIsOpen)
            {
                return(true);
            }

            // we're closed, so let's see if errors have made us so we should trip the circuit open
            HystrixHealthCounts healthCounts = commandMetrics.GetHealthCounts();

            // check if we are past the CircuitBreakerRequestVolumeThreshold
            if (healthCounts.GetTotalRequests() < configurationService.GetCircuitBreakerRequestVolumeThreshold())
            {
                // we are not past the minimum volume threshold for the statisticalWindow so we'll return false immediately and not calculate anything
                return(false);
            }

            // if error percentage is below threshold the circuit remains closed
            if (healthCounts.GetErrorPercentage() < configurationService.GetCircuitBreakerErrorThresholdPercentage())
            {
                return(false);
            }

            // failure rate is too high, trip the circuit (multiple threads can come to these lines, but do we care?)
            OpenCircuit();

            return(true);
        }
 public void ResetCounter()
 {
     counter.Reset();
     lastHealthCountsSnapshot = dateTimeProvider.GetCurrentTimeInMilliseconds();
     healthCountsSnapshot     = new HystrixHealthCounts(0, 0, 0);
 }