|
26 | 26 | import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
|
27 | 27 | import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisherFactory;
|
28 | 28 | import com.netflix.hystrix.strategy.properties.HystrixPropertiesFactory;
|
| 29 | +import org.junit.Test; |
| 30 | + |
| 31 | +import static org.junit.Assert.*; |
29 | 32 |
|
30 | 33 | /**
|
31 | 34 | * ThreadPool used to executed {@link HystrixCommand#run()} on separate threads when configured to do so with {@link HystrixCommandProperties#executionIsolationStrategy()}.
|
@@ -113,13 +116,48 @@ public interface HystrixThreadPool {
|
113 | 116 | return poolForKey;
|
114 | 117 | }
|
115 | 118 | }
|
| 119 | + |
| 120 | + /** |
| 121 | + * Initiate the shutdown of all {@link HystrixThreadPool} instances. |
| 122 | + * <p> |
| 123 | + * NOTE: This is NOT thread-safe if HystrixCommands are concurrently being executed |
| 124 | + * and causing thread-pools to initialize while also trying to shutdown. |
| 125 | + * </p> |
| 126 | + */ |
| 127 | + /* package */ static synchronized void shutdown() { |
| 128 | + for (HystrixThreadPool pool : threadPools.values()) { |
| 129 | + pool.getExecutor().shutdown(); |
| 130 | + } |
| 131 | + threadPools.clear(); |
| 132 | + } |
| 133 | + |
| 134 | + /** |
| 135 | + * Initiate the shutdown of all {@link HystrixThreadPool} instances and wait up to the given time on each pool to complete. |
| 136 | + * <p> |
| 137 | + * NOTE: This is NOT thread-safe if HystrixCommands are concurrently being executed |
| 138 | + * and causing thread-pools to initialize while also trying to shutdown. |
| 139 | + * </p> |
| 140 | + */ |
| 141 | + /* package */ static synchronized void shutdown(long timeout, TimeUnit unit) { |
| 142 | + for (HystrixThreadPool pool : threadPools.values()) { |
| 143 | + pool.getExecutor().shutdown(); |
| 144 | + } |
| 145 | + for (HystrixThreadPool pool : threadPools.values()) { |
| 146 | + try { |
| 147 | + pool.getExecutor().awaitTermination(timeout, unit); |
| 148 | + } catch (InterruptedException e) { |
| 149 | + throw new RuntimeException("Interrupted while waiting for thread-pools to terminate. Pools may not be correctly shutdown or cleared.", e); |
| 150 | + } |
| 151 | + } |
| 152 | + threadPools.clear(); |
| 153 | + } |
116 | 154 | }
|
117 | 155 |
|
118 | 156 | /**
|
119 | 157 | * @ExcludeFromJavadoc
|
120 | 158 | */
|
121 | 159 | @ThreadSafe
|
122 |
| - /* package */static class HystrixThreadPoolDefault implements HystrixThreadPool { |
| 160 | + /* package */ static class HystrixThreadPoolDefault implements HystrixThreadPool { |
123 | 161 | private final HystrixThreadPoolProperties properties;
|
124 | 162 | private final BlockingQueue<Runnable> queue;
|
125 | 163 | private final ThreadPoolExecutor threadPool;
|
@@ -174,4 +212,43 @@ public boolean isQueueSpaceAvailable() {
|
174 | 212 |
|
175 | 213 | }
|
176 | 214 |
|
| 215 | + public static class UnitTest { |
| 216 | + |
| 217 | + @Test |
| 218 | + public void testShutdown() { |
| 219 | + // other unit tests will probably have run before this so get the count |
| 220 | + int count = Factory.threadPools.size(); |
| 221 | + |
| 222 | + HystrixThreadPool pool = Factory.getInstance(HystrixThreadPoolKey.Factory.asKey("threadPoolFactoryTest"), |
| 223 | + HystrixThreadPoolProperties.Setter.getUnitTestPropertiesBuilder()); |
| 224 | + |
| 225 | + assertEquals(count + 1, Factory.threadPools.size()); |
| 226 | + assertFalse(pool.getExecutor().isShutdown()); |
| 227 | + |
| 228 | + Factory.shutdown(); |
| 229 | + |
| 230 | + // ensure all pools were removed from the cache |
| 231 | + assertEquals(0, Factory.threadPools.size()); |
| 232 | + assertTrue(pool.getExecutor().isShutdown()); |
| 233 | + } |
| 234 | + |
| 235 | + @Test |
| 236 | + public void testShutdownWithWait() { |
| 237 | + // other unit tests will probably have run before this so get the count |
| 238 | + int count = Factory.threadPools.size(); |
| 239 | + |
| 240 | + HystrixThreadPool pool = Factory.getInstance(HystrixThreadPoolKey.Factory.asKey("threadPoolFactoryTest"), |
| 241 | + HystrixThreadPoolProperties.Setter.getUnitTestPropertiesBuilder()); |
| 242 | + |
| 243 | + assertEquals(count + 1, Factory.threadPools.size()); |
| 244 | + assertFalse(pool.getExecutor().isShutdown()); |
| 245 | + |
| 246 | + Factory.shutdown(1, TimeUnit.SECONDS); |
| 247 | + |
| 248 | + // ensure all pools were removed from the cache |
| 249 | + assertEquals(0, Factory.threadPools.size()); |
| 250 | + assertTrue(pool.getExecutor().isShutdown()); |
| 251 | + } |
| 252 | + } |
| 253 | + |
177 | 254 | }
|
0 commit comments