Hystrix: Latency and Fault Tolerance for Distributed Systems



com.netflix.hystrix
Class HystrixCollapser<BatchReturnType,ResponseType,RequestArgumentType>

java.lang.Object
  extended by com.netflix.hystrix.HystrixCollapser<BatchReturnType,ResponseType,RequestArgumentType>
Type Parameters:
BatchReturnType - The type returned from the HystrixCommand that will be invoked on batch executions.
ResponseType - The type returned from this command.
RequestArgumentType - The type of the request argument. If multiple arguments are needed, wrap them in another object or a Tuple.
All Implemented Interfaces:
HystrixExecutable<ResponseType>

public abstract class HystrixCollapser<BatchReturnType,ResponseType,RequestArgumentType>
extends java.lang.Object
implements HystrixExecutable<ResponseType>

Collapse multiple requests into a single HystrixCommand execution based on a time window and optionally a max batch size.

This allows an object model to have multiple calls to the command that execute/queue many times in a short period (milliseconds) and have them all get batched into a single backend call.

Typically the time window is something like 10ms give or take.

NOTE: Do NOT retain any state within instances of this class.

It must be stateless or else it will be non-deterministic because most instances are discarded while some are retained and become the "collapsers" for all the ones that are discarded.


Nested Class Summary
static interface HystrixCollapser.CollapsedRequest<ResponseType,RequestArgumentType>
          A request argument RequestArgumentType that was collapsed for batch processing and needs a response ResponseType set on it by the executeBatch implementation.
static class HystrixCollapser.Scope
          The scope of request collapsing.
static class HystrixCollapser.Setter
          Fluent interface for arguments to the HystrixCollapser constructor.
 
Constructor Summary
protected HystrixCollapser()
          Collapser with default HystrixCollapserKey derived from the implementing class name and scoped to HystrixCollapser.Scope.REQUEST and default configuration.
protected HystrixCollapser(HystrixCollapser.Setter setter)
          Construct a HystrixCollapser with defined HystrixCollapser.Setter that allows injecting property and strategy overrides and other optional arguments.
protected HystrixCollapser(HystrixCollapserKey collapserKey)
          Collapser scoped to HystrixCollapser.Scope.REQUEST and default configuration.
 
Method Summary
protected abstract  HystrixCommand<BatchReturnType> createCommand(java.util.Collection<HystrixCollapser.CollapsedRequest<ResponseType,RequestArgumentType>> requests)
          Factory method to create a new HystrixCommand<BatchReturnType> command object each time a batch needs to be executed.
 ResponseType execute()
          Used for synchronous execution.
protected  java.lang.String getCacheKey()
          Key to be used for request caching.
 HystrixCollapserKey getCollapserKey()
          Key of the HystrixCollapser used for properties, metrics, caches, reporting etc.
abstract  RequestArgumentType getRequestArgument()
          The request arguments to be passed to the HystrixCommand.
 HystrixCollapser.Scope getScope()
          Scope of collapsing.
protected abstract  void mapResponseToRequests(BatchReturnType batchResponse, java.util.Collection<HystrixCollapser.CollapsedRequest<ResponseType,RequestArgumentType>> requests)
          Executed after the HystrixCommand<BatchReturnType> command created by HystrixCollapser.createCommand(java.util.Collection>) finishes processing (unless it fails) for mapping the <BatchReturnType> to the list of CollapsedRequest<ResponseType, RequestArgumentType> objects.
 rx.Observable<ResponseType> observe()
          Used for asynchronous execution with a callback by subscribing to the Observable.
 java.util.concurrent.Future<ResponseType> queue()
          Used for asynchronous execution.
protected  java.util.Collection<java.util.Collection<HystrixCollapser.CollapsedRequest<ResponseType,RequestArgumentType>>> shardRequests(java.util.Collection<HystrixCollapser.CollapsedRequest<ResponseType,RequestArgumentType>> requests)
          Override to split (shard) a batch of requests into multiple batches that will each call createCommand separately.
 rx.Observable<ResponseType> toObservable()
          A lazy Observable that will execute when subscribed to.
 rx.Observable<ResponseType> toObservable(rx.Scheduler observeOn)
          A lazy Observable that will execute when subscribed to.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

HystrixCollapser

protected HystrixCollapser()
Collapser with default HystrixCollapserKey derived from the implementing class name and scoped to HystrixCollapser.Scope.REQUEST and default configuration.


HystrixCollapser

protected HystrixCollapser(HystrixCollapserKey collapserKey)
Collapser scoped to HystrixCollapser.Scope.REQUEST and default configuration.

Parameters:
collapserKey - HystrixCollapserKey that identifies this collapser and provides the key used for retrieving properties, request caches, publishing metrics etc.

HystrixCollapser

protected HystrixCollapser(HystrixCollapser.Setter setter)
Construct a HystrixCollapser with defined HystrixCollapser.Setter that allows injecting property and strategy overrides and other optional arguments.

Null values will result in the default being used.

Parameters:
setter - Fluent interface for constructor arguments
Method Detail

getCollapserKey

public HystrixCollapserKey getCollapserKey()
Key of the HystrixCollapser used for properties, metrics, caches, reporting etc.

Returns:
HystrixCollapserKey identifying this HystrixCollapser instance

getScope

public HystrixCollapser.Scope getScope()
Scope of collapsing.

Default: HystrixCollapser.Scope.REQUEST (defined via constructor)

Returns:
HystrixCollapser.Scope that collapsing should be performed within.

getRequestArgument

public abstract RequestArgumentType getRequestArgument()
The request arguments to be passed to the HystrixCommand.

Typically this means to take the argument(s) provided to the constructor and return it here.

If there are multiple arguments that need to be bundled, create a single object to contain them, or use a Tuple.

Returns:
RequestArgumentType

createCommand

protected abstract HystrixCommand<BatchReturnType> createCommand(java.util.Collection<HystrixCollapser.CollapsedRequest<ResponseType,RequestArgumentType>> requests)
Factory method to create a new HystrixCommand<BatchReturnType> command object each time a batch needs to be executed.

Do not return the same instance each time. Return a new instance on each invocation.

Process the 'requests' argument into the arguments the command object needs to perform its work.

If a batch or requests needs to be split (sharded) into multiple commands, see HystrixCollapser.shardRequests(java.util.Collection>)

IMPLEMENTATION NOTE: Be fast (ie. <1ms) in this method otherwise it can block the Timer from executing subsequent batches. Do not do any processing beyond constructing the command and returning it.

Parameters:
requests - Collection<CollapsedRequest<ResponseType, RequestArgumentType>> containing HystrixCollapser.CollapsedRequest objects containing the arguments of each request collapsed in this batch.
Returns:
HystrixCommand<BatchReturnType> which when executed will retrieve results for the batch of arguments as found in the Collection of HystrixCollapser.CollapsedRequest objects

shardRequests

protected java.util.Collection<java.util.Collection<HystrixCollapser.CollapsedRequest<ResponseType,RequestArgumentType>>> shardRequests(java.util.Collection<HystrixCollapser.CollapsedRequest<ResponseType,RequestArgumentType>> requests)
Override to split (shard) a batch of requests into multiple batches that will each call createCommand separately.

The purpose of this is to allow collapsing to work for services that have sharded backends and batch executions that need to be shard-aware.

For example, a batch of 100 requests could be split into 4 different batches sharded on name (ie. a-g, h-n, o-t, u-z) that each result in a separate HystrixCommand being created and executed for them.

By default this method does nothing to the Collection and is a pass-thru.

Parameters:
requests - Collection<CollapsedRequest<ResponseType, RequestArgumentType>> containing HystrixCollapser.CollapsedRequest objects containing the arguments of each request collapsed in this batch.
Returns:
Collection of Collection<CollapsedRequest<ResponseType, RequestArgumentType>> objects sharded according to business rules.

The CollapsedRequest instances should not be modified or wrapped as the CollapsedRequest instance object contains state information needed to complete the execution.


mapResponseToRequests

protected abstract void mapResponseToRequests(BatchReturnType batchResponse,
                                              java.util.Collection<HystrixCollapser.CollapsedRequest<ResponseType,RequestArgumentType>> requests)
Executed after the HystrixCommand<BatchReturnType> command created by HystrixCollapser.createCommand(java.util.Collection>) finishes processing (unless it fails) for mapping the <BatchReturnType> to the list of CollapsedRequest<ResponseType, RequestArgumentType> objects.

IMPORTANT IMPLEMENTATION DETAIL => The expected contract (responsibilities) of this method implementation is:

Common code when <BatchReturnType> is List<ResponseType> is:

 int count = 0;
 for (CollapsedRequest<ResponseType, RequestArgumentType> request : requests) {
      request.setResponse(batchResponse.get(count++));
 }
 
For example if the types were <List<String>, String, String>:

 int count = 0;
 for (CollapsedRequest<String, String> request : requests) {
      request.setResponse(batchResponse.get(count++));
 }
 

Parameters:
batchResponse - The <BatchReturnType> returned from the HystrixCommand<BatchReturnType> command created by HystrixCollapser.createCommand(java.util.Collection>).

requests - Collection<CollapsedRequest<ResponseType, RequestArgumentType>> containing HystrixCollapser.CollapsedRequest objects containing the arguments of each request collapsed in this batch.

The HystrixCollapser.CollapsedRequest.setResponse(Object) or HystrixCollapser.CollapsedRequest.setException(Exception) must be called on each HystrixCollapser.CollapsedRequest in the Collection.


observe

public rx.Observable<ResponseType> observe()
Used for asynchronous execution with a callback by subscribing to the Observable.

This eagerly starts execution the same as HystrixCollapser.queue() and HystrixCollapser.execute(). A lazy Observable can be obtained from HystrixCollapser.toObservable().

Callback Scheduling

Use HystrixCollapser.toObservable(rx.Scheduler) to schedule the callback differently.

See https://github.com/Netflix/RxJava/wiki for more information.

Specified by:
observe in interface HystrixExecutable<ResponseType>
Returns:
Observable<R> that executes and calls back with the result of of HystrixCommand<BatchReturnType> execution after passing through HystrixCollapser.mapResponseToRequests(BatchReturnType, java.util.Collection>) to transform the <BatchReturnType> into <ResponseType>

toObservable

public rx.Observable<ResponseType> toObservable()
A lazy Observable that will execute when subscribed to.

Callback Scheduling

See https://github.com/Netflix/RxJava/wiki for more information.

Returns:
Observable<R> that lazily executes and calls back with the result of of HystrixCommand<BatchReturnType> execution after passing through HystrixCollapser.mapResponseToRequests(BatchReturnType, java.util.Collection>) to transform the <BatchReturnType> into <ResponseType>

toObservable

public rx.Observable<ResponseType> toObservable(rx.Scheduler observeOn)
A lazy Observable that will execute when subscribed to.

See https://github.com/Netflix/RxJava/wiki for more information.

Parameters:
observeOn - The Scheduler to execute callbacks on.
Returns:
Observable<R> that lazily executes and calls back with the result of of HystrixCommand<BatchReturnType> execution after passing through HystrixCollapser.mapResponseToRequests(BatchReturnType, java.util.Collection>) to transform the <BatchReturnType> into <ResponseType>

execute

public ResponseType execute()
Used for synchronous execution.

If HystrixCollapser.Scope.REQUEST is being used then synchronous execution will only result in collapsing if other threads are running within the same scope.

Specified by:
execute in interface HystrixExecutable<ResponseType>
Returns:
ResponseType Result of HystrixCommand<BatchReturnType> execution after passing through HystrixCollapser.mapResponseToRequests(BatchReturnType, java.util.Collection>) to transform the <BatchReturnType> into <ResponseType>
Throws:
HystrixRuntimeException - if an error occurs and a fallback cannot be retrieved

queue

public java.util.concurrent.Future<ResponseType> queue()
Used for asynchronous execution.

This will queue up the command and return a Future to get the result once it completes.

Specified by:
queue in interface HystrixExecutable<ResponseType>
Returns:
ResponseType Result of HystrixCommand<BatchReturnType> execution after passing through HystrixCollapser.mapResponseToRequests(BatchReturnType, java.util.Collection>) to transform the <BatchReturnType> into <ResponseType>
Throws:
HystrixRuntimeException - within an ExecutionException.getCause() (thrown by Future.get()) if an error occurs and a fallback cannot be retrieved

getCacheKey

protected java.lang.String getCacheKey()
Key to be used for request caching.

By default this returns null which means "do not cache".

To enable caching override this method and return a string key uniquely representing the state of a command instance.

If multiple command instances in the same request scope match keys then only the first will be executed and all others returned from cache.

Returns:
String cacheKey or null if not to cache