internal HealthCounts 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 = this.lastHealthCountsSnapshot;
            long currentTime = _clock.EllapsedTimeInMs;

            if ( currentTime - lastTime >= this._properties.MetricsHealthSnapshotIntervalInMilliseconds.Get() || healthCountsSnapshot.IsEmpty)
            {
                if (Interlocked.CompareExchange(ref this.lastHealthCountsSnapshot, currentTime, lastTime) == lastTime)
                {
                    long lastReset = _lastReset;
                    // 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(RollingNumberEvent.SUCCESS, lastReset);
                    long failure = _counter.GetRollingSum(RollingNumberEvent.FAILURE, lastReset); // fallbacks occur on this
                    long timeout = _counter.GetRollingSum(RollingNumberEvent.TIMEOUT, lastReset); // fallbacks occur on this
                    long threadPoolRejected = _counter.GetRollingSum(RollingNumberEvent.THREAD_POOL_REJECTED, lastReset); // fallbacks occur on this
                    long semaphoreRejected = _counter.GetRollingSum(RollingNumberEvent.SEMAPHORE_REJECTED, lastReset); // fallbacks occur on this
                    long shortCircuited = _counter.GetRollingSum(RollingNumberEvent.SHORT_CIRCUITED, lastReset); // fallbacks occur on this

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

                    if (totalCount > 0)
                    {
                        errorPercentage = (int)((double)errorCount / totalCount * 100);
                    }
                    healthCountsSnapshot = new HealthCounts(totalCount, errorCount, errorPercentage);
                }
            }
            return healthCountsSnapshot;
        }
 internal void Reset()
 {
     Interlocked.Exchange(ref _lastReset, _clock.EllapsedTimeInMs);
     healthCountsSnapshot = HealthCounts.Empty;
     _counter.Reset();
 }