diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/AbstractCommand.java b/hystrix-core/src/main/java/com/netflix/hystrix/AbstractCommand.java index 9ae21400b..17ee7123c 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/AbstractCommand.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/AbstractCommand.java @@ -94,6 +94,7 @@ protected static enum TimedOutStatus { protected final AtomicReference> timeoutTimer = new AtomicReference>(); protected final AtomicBoolean commandStarted = new AtomicBoolean(); + protected volatile boolean executionStarted = false; protected volatile boolean isExecutionComplete = false; /* @@ -445,8 +446,6 @@ public Observable call() { .doOnUnsubscribe(unsubscribeCommandCleanup); // perform cleanup once } - - private Observable applyHystrixSemantics(final AbstractCommand _cmd) { // mark that we're starting execution on the ExecutionHook // if this hook throws an exception, then a fast-fail occurs with no fallback. No state is left inconsistent @@ -584,6 +583,7 @@ private Observable executeCommandWithSpecifiedIsolation(final AbstractCommand @Override public Observable call() { executionResult = executionResult.setExecutionOccurred(); + executionStarted = true; metrics.markCommandStart(commandKey, threadPoolKey, ExecutionIsolationStrategy.THREAD); if (isCommandTimedOut.get() == TimedOutStatus.TIMED_OUT) { @@ -622,6 +622,7 @@ public Boolean call() { @Override public Observable call() { executionResult = executionResult.setExecutionOccurred(); + executionStarted = true; metrics.markCommandStart(commandKey, threadPoolKey, ExecutionIsolationStrategy.SEMAPHORE); // semaphore isolated // store the command that is being run @@ -843,7 +844,7 @@ private void cleanUpAfterResponseFromCache() { .setNotExecutedInThread(); ExecutionResult cacheOnlyForMetrics = ExecutionResult.from(HystrixEventType.RESPONSE_FROM_CACHE) .markUserThreadCompletion(latency); - metrics.markCommandDone(cacheOnlyForMetrics, commandKey, threadPoolKey); + metrics.markCommandDone(cacheOnlyForMetrics, commandKey, threadPoolKey, executionStarted); eventNotifier.markEvent(HystrixEventType.RESPONSE_FROM_CACHE, commandKey); } @@ -857,9 +858,9 @@ private void handleCommandEnd() { executionResult = executionResult.markUserThreadCompletion((int) userThreadLatency); ExecutionResult cancelled = executionResultAtTimeOfCancellation; if (cancelled == null) { - metrics.markCommandDone(executionResult, commandKey, threadPoolKey); + metrics.markCommandDone(executionResult, commandKey, threadPoolKey, executionStarted); } else { - metrics.markCommandDone(cancelled, commandKey, threadPoolKey); + metrics.markCommandDone(cancelled, commandKey, threadPoolKey, executionStarted); } } diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java index e2bd8b006..03b150cba 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java @@ -343,9 +343,9 @@ public int getCurrentConcurrentExecutionCount() { HystrixThreadEventStream.getInstance().commandExecutionStarted(commandKey, threadPoolKey, isolationStrategy, currentCount); } - /* package-private */ void markCommandDone(ExecutionResult executionResult, HystrixCommandKey commandKey, HystrixThreadPoolKey threadPoolKey) { + /* package-private */ void markCommandDone(ExecutionResult executionResult, HystrixCommandKey commandKey, HystrixThreadPoolKey threadPoolKey, boolean executionStarted) { HystrixThreadEventStream.getInstance().executionDone(executionResult, commandKey, threadPoolKey); - if (executionResult.executionOccurred()) { + if (executionStarted) { concurrentExecutionCount.decrementAndGet(); } }