/// <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); }
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); }
internal ResettingNumbersBucket(IClock clock, IConfigurableValue <long> periodMillis) { _clock = clock; _periodMillis = periodMillis; _counters = CreateCounters(); _lastResetAtTime = clock.GetMillisecondTimestamp(); }
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); }
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(); }