示例#1
0
        private T InnerExecute <T>(Func <T> primaryFunction, Func <IEnumerable <Exception>, T> fallbackFunction, CancellationTokenSource cancellationTokenSource)
        {
            if (!ConfigurationService.GetHystrixCommandEnabled())
            {
                return(primaryFunction.Invoke());
            }

            var innerExceptions = new List <Exception>();

            Stopwatch userThreadStopWatch = Stopwatch.StartNew();

            if (CircuitBreaker.AllowRequest())
            {
                CommandMetrics.IncrementConcurrentExecutionCount();
                ThreadPoolMetrics.MarkThreadExecution();

                Stopwatch commandStopWatch = Stopwatch.StartNew();

                try
                {
                    var result = timeoutWrapper.Execute(primaryFunction, cancellationTokenSource);

                    commandStopWatch.Stop();

                    CircuitBreaker.CloseCircuit();

                    CommandMetrics.MarkSuccess();

                    return(result);
                }
                catch (HystrixTimeoutException hte)
                {
                    commandStopWatch.Stop();
                    CommandMetrics.MarkTimeout();
                    innerExceptions.Add(hte);
                }
                catch (Exception ex)
                {
                    commandStopWatch.Stop();
                    CommandMetrics.MarkFailure();
                    CommandMetrics.MarkExceptionThrown();
                    innerExceptions.Add(ex);
                }
                finally
                {
                    // track command execution time
                    commandStopWatch.Stop();
                    CommandMetrics.AddCommandExecutionTime(commandStopWatch.Elapsed.TotalMilliseconds);

                    CommandMetrics.DecrementConcurrentExecutionCount();
                    ThreadPoolMetrics.MarkThreadCompletion();

                    // track execution time including threading overhead
                    userThreadStopWatch.Stop();
                    CommandMetrics.AddUserThreadExecutionTime(userThreadStopWatch.Elapsed.TotalMilliseconds);
                }
            }
            else
            {
                CommandMetrics.MarkShortCircuited();

                // track execution time including threading overhead
                userThreadStopWatch.Stop();
                CommandMetrics.AddUserThreadExecutionTime(userThreadStopWatch.Elapsed.TotalMilliseconds);
            }

            T fallbackResult = fallbackFunction.Invoke(innerExceptions);

            CommandMetrics.MarkFallbackSuccess();

            return(fallbackResult);
        }