From 951c6f9daa6dc469911b2e29a77fd85d90b4ab1e Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Mon, 8 May 2017 06:37:34 -0700 Subject: [PATCH] Only create the HystrixContextRunnable for running the timeout fallback when the timeout actually occurs (not eagerly) --- .../com/netflix/hystrix/AbstractCommand.java | 22 +++++++++---------- .../concurrency/HystrixContextRunnable.java | 6 ++++- 2 files changed, 16 insertions(+), 12 deletions(-) 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 a93273d90..f9c69657b 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/AbstractCommand.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/AbstractCommand.java @@ -1132,17 +1132,8 @@ public Subscriber call(final Subscriber child) { // if the child unsubscribes we unsubscribe our parent as well child.add(s); - /* - * Define the action to perform on timeout outside of the TimerListener to it can capture the HystrixRequestContext - * of the calling thread which doesn't exist on the Timer thread. - */ - final HystrixContextRunnable timeoutRunnable = new HystrixContextRunnable(originalCommand.concurrencyStrategy, new Runnable() { - - @Override - public void run() { - child.onError(new HystrixTimeoutException()); - } - }); + //capture the HystrixRequestContext upfront so that we can use it in the timeout thread later + final HystrixRequestContext hystrixRequestContext = HystrixRequestContext.getContextForCurrentThread(); TimerListener listener = new TimerListener() { @@ -1157,6 +1148,15 @@ public void tick() { // shut down the original request s.unsubscribe(); + final HystrixContextRunnable timeoutRunnable = new HystrixContextRunnable(originalCommand.concurrencyStrategy, hystrixRequestContext, new Runnable() { + + @Override + public void run() { + child.onError(new HystrixTimeoutException()); + } + }); + + timeoutRunnable.run(); //if it did not start, then we need to mark a command start for concurrency metrics, and then issue the timeout } diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/concurrency/HystrixContextRunnable.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/concurrency/HystrixContextRunnable.java index 3c36addd4..b95a517a9 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/concurrency/HystrixContextRunnable.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/concurrency/HystrixContextRunnable.java @@ -34,6 +34,10 @@ public HystrixContextRunnable(Runnable actual) { } public HystrixContextRunnable(HystrixConcurrencyStrategy concurrencyStrategy, final Runnable actual) { + this(concurrencyStrategy, HystrixRequestContext.getContextForCurrentThread(), actual); + } + + public HystrixContextRunnable(final HystrixConcurrencyStrategy concurrencyStrategy, final HystrixRequestContext hystrixRequestContext, final Runnable actual) { this.actual = concurrencyStrategy.wrapCallable(new Callable() { @Override @@ -43,7 +47,7 @@ public Void call() throws Exception { } }); - this.parentThreadState = HystrixRequestContext.getContextForCurrentThread(); + this.parentThreadState = hystrixRequestContext; } @Override