示例#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);
        }