예제 #1
0
        /// <summary>
        /// Indicates that a recently-completed operation was successful.
        ///
        /// If the breaker is tripped and <code>MarkSuccess()</code> is called, the breaker will be fixed.
        /// The operation's elapsed duration (in milliseconds) is used to ensure the operation being checked
        /// began before the breaker was initially tripped.
        /// </summary>
        public void MarkSuccess(long elapsedMillis)
        {
            if (_state != State.Tripped || _clock.GetMillisecondTimestamp() - elapsedMillis < _lastTrippedTimestamp)
            {
                // Ignore.
                return;
            }

            _log.Info($"Fixed Breaker={_key}");

            _state = State.Fixed;
            _metrics.Reset();

            _metricEvents.BreakerFixed(Name);
        }
예제 #2
0
        public MetricsSnapshot GetSnapshot()
        {
            var lastSnapshotTime = _lastSnapshotTimestamp;
            var currentTime      = _clock.GetMillisecondTimestamp();

            if (_lastSnapshot == null || currentTime - lastSnapshotTime > _config.GetSnapshotTtlMillis(_key))
            {
                // Try to update the _lastSnapshotTimestamp. If we update it, this thread will take on the authority of updating
                // the snapshot. CompareExchange returns the original result, so if it's different from currentTime, we successfully exchanged.
                if (Interlocked.CompareExchange(ref _lastSnapshotTimestamp, currentTime, _lastSnapshotTimestamp) != currentTime)
                {
                    // TODO rob.hruska 11/8/2013 - May be inaccurate if counts are incremented as we're querying these.
                    var success = _resettingNumbersBucket.GetCount(CounterMetric.CommandSuccess);
                    var failure = _resettingNumbersBucket.GetCount(CounterMetric.CommandFailure);
                    var total   = success + failure;

                    int errorPercentage;
                    if (total == 0)
                    {
                        errorPercentage = 0;
                    }
                    else
                    {
                        errorPercentage = (int)(success == 0 ? 100 : (failure / (double)total) * 100);
                    }

                    _lastSnapshot = new MetricsSnapshot(total, errorPercentage);
                }
            }

            return(_lastSnapshot);
        }
예제 #3
0
 internal ResettingNumbersBucket(IClock clock, IConfigurableValue <long> periodMillis)
 {
     _clock           = clock;
     _periodMillis    = periodMillis;
     _counters        = CreateCounters();
     _lastResetAtTime = clock.GetMillisecondTimestamp();
 }
예제 #4
0
 internal ResettingNumbersBucket(IClock clock, IConfigurableValue<long> periodMillis)
 {
     _clock = clock;
     _periodMillis = periodMillis;
     _counters = CreateCounters();
     _lastResetAtTime = clock.GetMillisecondTimestamp();
 }
        /// <summary>
        /// Indicates that a recently-completed operation was successful.
        ///
        /// If the breaker is tripped and <code>MarkSuccess()</code> is called, the breaker will be fixed.
        /// The operation's elapsed duration (in milliseconds) is used to ensure the operation being checked
        /// began before the breaker was initially tripped.
        /// </summary>
        public void MarkSuccess(long elapsedMillis)
        {
            if (_state != State.Tripped || _clock.GetMillisecondTimestamp() - elapsedMillis < _lastTrippedTimestamp)
            {
                // Ignore.
                _stats.Event(StatsPrefix + " MarkSuccess", "Ignored", null);
                return;
            }

            Log.InfoFormat("Fixed Breaker={0}", _key);

            _state = State.Fixed;
            _metrics.Reset();

            _stats.Event(StatsPrefix + " MarkSuccess", "Fixed", null);
        }
예제 #6
0
        internal void Increment(CounterMetric metric)
        {
            // Notes:
            // - If we have long periods with no stats, we won't reset until we get one.
            // - This is a "pretty close" implementation.
            //   - Accuracy on Gets isn't 100% and is subject to racing.
            //   - We may write metrics into "old" buckets immediately before resetting at the interval.

            if (_clock.GetMillisecondTimestamp() - _lastResetAtTime > _periodMillis.Value)
            {
                Reset();
            }

            // See note in Reset() about potential for losing current window counts here.

            _counters[(int)metric].Increment();
        }
        internal ResettingNumbersBucket(GroupKey key, IClock clock, IFailurePercentageCircuitBreakerConfig config, IMjolnirLogFactory logFactory)
        {
            _key    = key;
            _clock  = clock ?? throw new ArgumentNullException(nameof(clock));
            _config = config ?? throw new ArgumentNullException(nameof(config));

            if (logFactory == null)
            {
                throw new ArgumentNullException(nameof(logFactory));
            }

            _log = logFactory.CreateLog <ResettingNumbersBucket>();

            if (_log == null)
            {
                throw new InvalidOperationException($"{nameof(IMjolnirLogFactory)} implementation returned null from {nameof(IMjolnirLogFactory.CreateLog)} for type {typeof(ResettingNumbersBucket)}, please make sure the implementation returns a non-null log for all calls to {nameof(IMjolnirLogFactory.CreateLog)}");
            }

            _counters        = CreateCounters();
            _lastResetAtTime = clock.GetMillisecondTimestamp();
        }