com.netflix.hystrix.strategy.concurrency
Class HystrixConcurrencyStrategy

java.lang.Object
  extended by com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy

public abstract class HystrixConcurrencyStrategy
extends java.lang.Object

Abstract class for defining different behavior or implementations for concurrency related aspects of the system with default implementations.

For example, every Callable executed by HystrixCommand will call HystrixConcurrencyStrategy.wrapCallable(Callable) to give a chance for custom implementations to decorate the Callable with additional behavior.

Custom implementations of this interface can be used to override default behavior via 2 mechanisms:

1) Injection

Implementations can be injected into HystrixCommand and HystrixCollapser implementation constructors.

2) Plugin

Using HystrixPlugins.registerConcurrencyStrategy(com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy) an implementation can be registered globally to take precedence and override all other implementations.

The order of precedence is:

  1. plugin registered globally using HystrixPlugins.registerConcurrencyStrategy(com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy)
  2. injected via HystrixCommand and HystrixCollapser constructors
  3. default implementation HystrixConcurrencyStrategyDefault

The injection approach is effective for HystrixCommand and HystrixCollapser implementations where you wish to have a different default strategy without overriding all implementations. It is also useful when distributing a library where static override should not be used.

The globally registered plugin is useful when using commands from 3rd party libraries and you want to override the strategy for all implementations in your entire system.


Constructor Summary
HystrixConcurrencyStrategy()
           
 
Method Summary
 java.util.concurrent.BlockingQueue<java.lang.Runnable> getBlockingQueue(int maxQueueSize)
          Factory method to provide instance of BlockingQueue<Runnable> used for each ThreadPoolExecutor as constructed in HystrixConcurrencyStrategy.getThreadPool(com.netflix.hystrix.HystrixThreadPoolKey, com.netflix.hystrix.strategy.properties.HystrixProperty, com.netflix.hystrix.strategy.properties.HystrixProperty, com.netflix.hystrix.strategy.properties.HystrixProperty, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue).
<T> HystrixRequestVariable<T>
getRequestVariable(HystrixRequestVariableLifecycle<T> rv)
          Factory method to return an implementation of HystrixRequestVariable that behaves like a ThreadLocal except that it is scoped to a request instead of a thread.
 java.util.concurrent.ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixProperty<java.lang.Integer> corePoolSize, HystrixProperty<java.lang.Integer> maximumPoolSize, HystrixProperty<java.lang.Integer> keepAliveTime, java.util.concurrent.TimeUnit unit, java.util.concurrent.BlockingQueue<java.lang.Runnable> workQueue)
          Factory method to provide ThreadPoolExecutor instances as desired.
<T> java.util.concurrent.Callable<T>
wrapCallable(java.util.concurrent.Callable<T> callable)
          Provides an opportunity to wrap/decorate a Callable<T> before execution.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

HystrixConcurrencyStrategy

public HystrixConcurrencyStrategy()
Method Detail

getThreadPool

public java.util.concurrent.ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
                                                             HystrixProperty<java.lang.Integer> corePoolSize,
                                                             HystrixProperty<java.lang.Integer> maximumPoolSize,
                                                             HystrixProperty<java.lang.Integer> keepAliveTime,
                                                             java.util.concurrent.TimeUnit unit,
                                                             java.util.concurrent.BlockingQueue<java.lang.Runnable> workQueue)
Factory method to provide ThreadPoolExecutor instances as desired.

Note that the corePoolSize, maximumPoolSize and keepAliveTime values will be dynamically set during runtime if their values change using the ThreadPoolExecutor.setCorePoolSize(int), ThreadPoolExecutor.setMaximumPoolSize(int) and ThreadPoolExecutor.setKeepAliveTime(long, java.util.concurrent.TimeUnit) methods.

Default Implementation

Implementation using standard java.util.concurrent.ThreadPoolExecutor

Parameters:
threadPoolKey - HystrixThreadPoolKey representing the HystrixThreadPool that this ThreadPoolExecutor will be used for.
corePoolSize - Core number of threads requested via properties (or system default if no properties set).
maximumPoolSize - Max number of threads requested via properties (or system default if no properties set).
keepAliveTime - Keep-alive time for threads requested via properties (or system default if no properties set).
unit - TimeUnit corresponding with keepAliveTime
workQueue - BlockingQueue<Runnable> as provided by HystrixConcurrencyStrategy.getBlockingQueue(int)
Returns:
instance of ThreadPoolExecutor

getBlockingQueue

public java.util.concurrent.BlockingQueue<java.lang.Runnable> getBlockingQueue(int maxQueueSize)
Factory method to provide instance of BlockingQueue<Runnable> used for each ThreadPoolExecutor as constructed in HystrixConcurrencyStrategy.getThreadPool(com.netflix.hystrix.HystrixThreadPoolKey, com.netflix.hystrix.strategy.properties.HystrixProperty, com.netflix.hystrix.strategy.properties.HystrixProperty, com.netflix.hystrix.strategy.properties.HystrixProperty, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue).

Note: The maxQueueSize value is provided so any type of queue can be used but typically an implementation such as SynchronousQueue without a queue (just a handoff) is preferred as queueing is an anti-pattern to be purposefully avoided for latency tolerance reasons.

Default Implementation

Implementation returns SynchronousQueue when maxQueueSize <= 0 or LinkedBlockingQueue when maxQueueSize > 0.

Parameters:
maxQueueSize - The max size of the queue requested via properties (or system default if no properties set).
Returns:
instance of BlockingQueue<Runnable>

wrapCallable

public <T> java.util.concurrent.Callable<T> wrapCallable(java.util.concurrent.Callable<T> callable)
Provides an opportunity to wrap/decorate a Callable<T> before execution.

This can be used to inject additional behavior such as copying of thread state (such as ThreadLocal).

Default Implementation

Pass-thru that does no wrapping.

Parameters:
callable - Callable<T> to be executed via a ThreadPoolExecutor
Returns:
Callable<T> either as a pass-thru or wrapping the one given

getRequestVariable

public <T> HystrixRequestVariable<T> getRequestVariable(HystrixRequestVariableLifecycle<T> rv)
Factory method to return an implementation of HystrixRequestVariable that behaves like a ThreadLocal except that it is scoped to a request instead of a thread.

For example, if a request starts with an HTTP request and ends with the HTTP response, then HystrixRequestVariable should be initialized at the beginning, available on any and all threads spawned during the request and then cleaned up once the HTTP request is completed.

If this method is implemented it is generally necessary to also implemented HystrixConcurrencyStrategy.wrapCallable(Callable) in order to copy state from parent to child thread.

Parameters:
rv - HystrixRequestVariableLifecycle with lifecycle implementations from Hystrix
Returns:
HystrixRequestVariable<T>