Showing posts with label circuitbreaker. Show all posts
Showing posts with label circuitbreaker. Show all posts

Thursday, October 22, 2015

Hystrix demistified

Hystrix is simple in itself and very easy to understand, still some get confused about how it works.
So let me give a simple example of how it works.
I have taken below example from : Hystrix site Getting-Started
public class CommandHelloWorld extends HystrixCommand<String> {

    private final String name;

    public CommandHelloWorld(String name) {
        super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
        this.name = name;
    }

    @Override
    protected String run() {
        // a real example would do work like a network call here
        return "Hello " + name + "!";
    }
}

String s = new CommandHelloWorld("Bob").execute();
Let us demystify this code:

First:

You need to extend the HystrixCommand to use Hystrix circuit breaker.
HystrixCommand<String>  // This statement tells what your Hystrix command is going to return when your execute it. (Return value of run() method)

HystrixCommand<AnyObject>

HystrixCommand<Anything> 

Second:

Constructor behave as the entry point of your Hystrix Command. You should define it in such a way that values passed can be used to:
1) defining Hystrix Command name, group name , Cache key etc.
2)  help execute the run() method to do the actual task by providing needed element.
    public CommandHelloWorld(String name) {
        }

Example 1:

In above example this parameter is used in run method.
    public CommandHelloWorld(String name) {
    super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
    }

Example 2:

The parameter here are used to define Hystrix Command and are used in run method to make a http call.
   public CommandHelloWorld(String groupKeyName,String commandName, HttpClient httpClient, HttpContext httpContext, HttpRequestBase httpRequest) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKeyName)).andCommandKey(HystrixCommandKey.Factory.asKey(commandName)));
    }
    

Example 3:

The parameter here are used to define Hystrix Command and are used in run jdbc call.
public CommandHelloWorld(String groupKeyName,String commandName, JDBCTemplate jdbcTemplate) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKeyName)).andCommandKey(HystrixCommandKey.Factory.asKey(commandName)));
    }

Third:

This call is to configure the HystrixCommand.
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));  // this define the group name of your Hystrix command.

Hystrix define two constructror for configuration:

protected HystrixCommand(HystrixCommandGroupKey group) { // Example 1 
        this(new HystrixCommand.Setter(group, null));
    }

protected HystrixCommand(HystrixCommand.Setter setter) { // Example 2 or 3
        this(setter.groupKey, setter.commandKey, setter.threadPoolKey, (HystrixCircuitBreaker)null, (HystrixThreadPool)null, setter.commandPropertiesDefaults, setter.threadPoolPropertiesDefaults, (HystrixCommandMetrics)null, (HystrixCommand.TryableSemaphore)null, (HystrixCommand.TryableSemaphore)null, (HystrixPropertiesStrategy)null, (HystrixCommandExecutionHook)null);
    }

Fourth:

To implement the HystrixComman override the run() method. This is where you will do all the task as per your requirement.
@Override
    protected String run() {
        // a real example would do work like a network call here
        return "Hello " + name + "!";
    }

Fifth:

The above created command be used like this :String s = new CommandHelloWorld("Bob").execute(); // this will internally call the run() method