From ce1caab677b33cac0cedc92c9ae5762f4d36a522 Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Wed, 31 Aug 2016 14:47:08 -0700 Subject: [PATCH] Made the user-defined fallback calculation more general * Should allow Javanica to re-implement this concept straightforwardly --- .../com/netflix/hystrix/AbstractCommand.java | 31 ++++--------------- .../com/netflix/hystrix/HystrixCommand.java | 20 ++++++++++++ .../hystrix/HystrixObservableCommand.java | 18 +++++++++++ 3 files changed, 44 insertions(+), 25 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 8e4bec044..89a7856c7 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/AbstractCommand.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/AbstractCommand.java @@ -134,7 +134,7 @@ protected enum ThreadState { // on the repetitive string processing that will occur on the same classes over and over again private static ConcurrentHashMap, String> defaultNameCache = new ConcurrentHashMap, String>(); - private static ConcurrentHashMap commandContainsFallback = new ConcurrentHashMap(); + protected static ConcurrentHashMap commandContainsFallback = new ConcurrentHashMap(); /* package */static String getDefaultNameFromClass(Class cls) { String fromCache = defaultNameCache.get(cls); @@ -833,7 +833,7 @@ public void call() { // acquire a permit if (fallbackSemaphore.tryAcquire()) { try { - if (isFallbackUserSupplied(this)) { + if (isFallbackUserDefined()) { executionHook.onFallbackStart(this); fallbackExecutionChain = getFallbackObservable(); } else { @@ -1254,32 +1254,13 @@ protected TryableSemaphore getExecutionSemaphore() { /** * Each concrete implementation of AbstractCommand should return the name of the fallback method as a String * This will be used to determine if the fallback "exists" for firing the onFallbackStart/onFallbackError hooks + * @deprecated This functionality is replaced by {@link #isFallbackUserDefined}, which is less implementation-aware * @return method name of fallback */ + @Deprecated protected abstract String getFallbackMethodName(); - /** - * For the given command instance, does it define an actual fallback method? - * @param cmd command instance - * @return true iff there is a user-supplied fallback method on the given command instance - */ - /*package-private*/ static boolean isFallbackUserSupplied(final AbstractCommand cmd) { - HystrixCommandKey commandKey = cmd.commandKey; - Boolean containsFromMap = commandContainsFallback.get(commandKey); - if (containsFromMap != null) { - return containsFromMap; - } else { - Boolean toInsertIntoMap; - try { - cmd.getClass().getDeclaredMethod(cmd.getFallbackMethodName()); - toInsertIntoMap = true; - } catch (NoSuchMethodException nsme) { - toInsertIntoMap = false; - } - commandContainsFallback.put(commandKey, toInsertIntoMap); - return toInsertIntoMap; - } - } + protected abstract boolean isFallbackUserDefined(); /** * @return {@link HystrixCommandGroupKey} used to group together multiple {@link AbstractCommand} objects. @@ -1497,7 +1478,7 @@ private Exception wrapWithOnExecutionErrorHook(Throwable t) { private Exception wrapWithOnFallbackErrorHook(Throwable t) { Exception e = getExceptionFromThrowable(t); try { - if (isFallbackUserSupplied(this)) { + if (isFallbackUserDefined()) { return executionHook.onFallbackError(this, e); } else { return e; diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommand.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommand.java index 43e06d787..4e03958bb 100755 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommand.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommand.java @@ -15,6 +15,7 @@ */ package com.netflix.hystrix; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -44,6 +45,7 @@ */ public abstract class HystrixCommand extends AbstractCommand implements HystrixExecutable, HystrixInvokableInfo, HystrixObservable { + /** * Construct a {@link HystrixCommand} with defined {@link HystrixCommandGroupKey}. *

@@ -461,6 +463,24 @@ protected String getFallbackMethodName() { return "getFallback"; } + @Override + protected boolean isFallbackUserDefined() { + Boolean containsFromMap = commandContainsFallback.get(commandKey); + if (containsFromMap != null) { + return containsFromMap; + } else { + Boolean toInsertIntoMap; + try { + getClass().getDeclaredMethod("getFallback"); + toInsertIntoMap = true; + } catch (NoSuchMethodException nsme) { + toInsertIntoMap = false; + } + commandContainsFallback.put(commandKey, toInsertIntoMap); + return toInsertIntoMap; + } + } + @Override protected boolean commandIsScalar() { return true; diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixObservableCommand.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixObservableCommand.java index b9cf8c9c1..fe4d08896 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixObservableCommand.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixObservableCommand.java @@ -67,6 +67,24 @@ protected String getFallbackMethodName() { return "resumeWithFallback"; } + @Override + protected boolean isFallbackUserDefined() { + Boolean containsFromMap = commandContainsFallback.get(commandKey); + if (containsFromMap != null) { + return containsFromMap; + } else { + Boolean toInsertIntoMap; + try { + getClass().getDeclaredMethod("resumeWithFallback"); + toInsertIntoMap = true; + } catch (NoSuchMethodException nsme) { + toInsertIntoMap = false; + } + commandContainsFallback.put(commandKey, toInsertIntoMap); + return toInsertIntoMap; + } + } + @Override protected boolean commandIsScalar() { return false;