Beispiel #1
0
        public async Task <TResult> ExecuteWithBreakerAsync <TResult>(AsyncCommand <TResult> command, CancellationToken ct)
        {
            var breaker = _circuitBreakerFactory.GetCircuitBreaker(command.BreakerKey);

            if (!breaker.IsAllowing())
            {
                _metricEvents.RejectedByBreaker(breaker.Name, command.Name);
                throw new CircuitBreakerRejectedException();
            }

            TResult result;

            var success            = true;
            var breakerStopwatch   = Stopwatch.StartNew();
            var executionStopwatch = Stopwatch.StartNew();

            try
            {
                // Await here so we can catch the Exception and track the state.
                result = await command.ExecuteAsync(ct).ConfigureAwait(false);

                executionStopwatch.Stop();

                breaker.MarkSuccess(breakerStopwatch.ElapsedMilliseconds);
                breaker.Metrics.MarkCommandSuccess();
            }
            catch (Exception e)
            {
                executionStopwatch.Stop();
                success = false;

                if (_ignoredExceptions.IsExceptionIgnored(e.GetType()))
                {
                    success = true;
                    breaker.MarkSuccess(breakerStopwatch.ElapsedMilliseconds);
                    breaker.Metrics.MarkCommandSuccess();
                }
                else
                {
                    breaker.Metrics.MarkCommandFailure();
                }

                throw;
            }
            finally
            {
                command.ExecutionTimeMillis = executionStopwatch.Elapsed.TotalMilliseconds;

                if (success)
                {
                    _metricEvents.BreakerSuccessCount(breaker.Name, command.Name);
                }
                else
                {
                    _metricEvents.BreakerFailureCount(breaker.Name, command.Name);
                }
            }

            return(result);
        }