From 976f2fb0753fb870e6d84cef3c7a2562e00bb6fc Mon Sep 17 00:00:00 2001 From: Ben Christensen Date: Fri, 15 Feb 2013 12:07:01 -0800 Subject: [PATCH] Hystrix.reset for lifecycle management I'm changing the design from the previous commits so it's more abstract and can handle any type of resources needing cleanup, not just threadpools. https://github.com/Netflix/RxJava/issues/45 --- .../java/com/netflix/hystrix/Hystrix.java | 48 +++++++++++++++++++ .../hystrix/HystrixCircuitBreaker.java | 7 +++ .../com/netflix/hystrix/HystrixCollapser.java | 22 ++++----- .../hystrix/HystrixCommandMetrics.java | 7 +++ .../netflix/hystrix/util/HystrixTimer.java | 11 +++++ 5 files changed, 83 insertions(+), 12 deletions(-) create mode 100644 hystrix-core/src/main/java/com/netflix/hystrix/Hystrix.java diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/Hystrix.java b/hystrix-core/src/main/java/com/netflix/hystrix/Hystrix.java new file mode 100644 index 000000000..6e97419eb --- /dev/null +++ b/hystrix-core/src/main/java/com/netflix/hystrix/Hystrix.java @@ -0,0 +1,48 @@ +package com.netflix.hystrix; + +import java.util.concurrent.TimeUnit; + +/** + * Lifecycle management of Hystrix. + */ +public class Hystrix { + + /** + * Reset state and release resources in use (such as thread-pools). + *

+ * NOTE: This can result in race conditions if HystrixCommands are concurrently being executed. + *

+ */ + public static void reset() { + // shutdown thread-pools + HystrixThreadPool.Factory.shutdown(); + _reset(); + } + + /** + * Reset state and release resources in use (such as threadpools) and wait for completion. + *

+ * NOTE: This can result in race conditions if HystrixCommands are concurrently being executed. + *

+ * + * @param time time to wait for thread-pools to shutdown + * @param unit {@link TimeUnit} for
time
to wait for thread-pools to shutdown + */ + public static void reset(long time, TimeUnit unit) { + // shutdown thread-pools + HystrixThreadPool.Factory.shutdown(time, unit); + _reset(); + } + + /** + * Reset logic that doesn't have time/TimeUnit arguments. + */ + private static void _reset() { + // clear metrics + HystrixCommandMetrics.reset(); + // clear collapsers + HystrixCollapser.reset(); + // clear circuit breakers + HystrixCircuitBreaker.Factory.reset(); + } +} diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCircuitBreaker.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCircuitBreaker.java index 1c563def4..7bb208ccb 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCircuitBreaker.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCircuitBreaker.java @@ -113,6 +113,13 @@ public static HystrixCircuitBreaker getInstance(HystrixCommandKey key, HystrixCo public static HystrixCircuitBreaker getInstance(HystrixCommandKey key) { return circuitBreakersByCommand.get(key.name()); } + + /** + * Clears all circuit breakers. If new requests come in instances will be recreated. + */ + /* package */ static void reset() { + circuitBreakersByCommand.clear(); + } } /** diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapser.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapser.java index a53f07ed7..aae93bc81 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapser.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapser.java @@ -346,18 +346,6 @@ public Future queue() { return response; } - /** - * Reset the global and request-scoped state for the given collapser key. - * - * This is intended to support uses of collapsers in an environment like a REPL - * where the definition of a collapser may change. It is not thread-safe and should - * not be used in a production environment. - */ - public static void resetCollapser(HystrixCollapserKey key) { - globalScopedCollapsers.remove(key.name()); - requestScopedCollapsers.remove(key.name()); - } - /** * Static global cache of RequestCollapsers for Scope.GLOBAL */ @@ -994,6 +982,16 @@ protected String getCacheKey() { return null; } + /** + * Clears all state. If new requests come in instances will be recreated and metrics started from scratch. + */ + /* package */ static void reset() { + defaultNameCache.clear(); + globalScopedCollapsers.clear(); + requestScopedCollapsers.clear(); + RealCollapserTimer.timer.reset(); + } + private static String getDefaultNameFromClass(@SuppressWarnings("rawtypes") Class cls) { String fromCache = defaultNameCache.get(cls); if (fromCache != null) { 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 74f163c57..a75c3bfdb 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java @@ -100,6 +100,13 @@ public static Collection getInstances() { return Collections.unmodifiableCollection(metrics.values()); } + /** + * Clears all state from metrics. If new requests come in instances will be recreated and metrics started from scratch. + */ + /* package */ static void reset() { + metrics.clear(); + } + private final HystrixCommandProperties properties; private final HystrixRollingNumber counter; private final HystrixRollingPercentile percentileExecution; diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/util/HystrixTimer.java b/hystrix-core/src/main/java/com/netflix/hystrix/util/HystrixTimer.java index d87e4329a..1d1909679 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/util/HystrixTimer.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/util/HystrixTimer.java @@ -66,6 +66,17 @@ public static HystrixTimer getInstance() { return INSTANCE; } + /** + * Clears all listeners. + *

+ * NOTE: This will result in race conditions if {@link #addTimerListener(com.netflix.hystrix.util.HystrixTimer.TimerListener)} is being concurrently called. + *

+ */ + public static void reset() { + INSTANCE.listenersPerInterval.clear(); + INSTANCE.intervals.clear(); + } + private TickThread tickThread = new TickThread(); private ConcurrentHashMap>> listenersPerInterval = new ConcurrentHashMap>>(); private ConcurrentLinkedQueue intervals = new ConcurrentLinkedQueue();