Circuit Breaker pattern – Java implement Part 2

Base on part 1, today i’m going to implement circuit-breaker pattern with java. A few functions i will to perform as follows

  • Use breaker pattern to build acts proxy for service remote call.
  • Support config timeout and number of retry to execute command.
  • Compatible with multiple threads model.
  • Inheritance and flexibility.
  • Demo run with simple application.

UML for core implement Breaker pattern

circuit-breaker2

BreakerExecute.java is main class implement proxy acts for remote call

+ Return fail when state of service is OPEN

if (state == BreakerState.OPEN)
{
   try {
      error(new BreakerRejectException(), null);
      commandQueues.add(currentCommand);
      continue;
   }
      catch (Exception errHandle) {
      LOGGER.error(errHandle, errHandle);
   }
}

+ Change state to CLOSE when have a remote call is successful

currentCommand.run();
if (state == BreakerState.HALF_OPEN) {
   state = BreakerState.CLOSE;
   numberFailure.set(0);
}

+ Retry execute command with number of re-invoke is limited

Integer counter = mapRetryCommand.get(currentCommand.getId());
if(counter == null){
   counter = 1;
   mapRetryCommand.put(currentCommand.getId(), counter);
}
if (counter < numberAttempts) {
   commandQueues.add(currentCommand);
   counter++;
   mapRetryCommand.put(currentCommand.getId(), counter);
} else {
   mapRetryCommand.remove(currentCommand.getId());
try {
   error(new BreakerExpiredException(), currentCommand);
} catch (Exception errHandle) {
   LOGGER.error(errHandle, errHandle);
}

+ Change state CLOSE to OPEN when the number of recent failure exceed a specified threshold.

if (state == BreakerState.CLOSE) {
   if (numberFailure.incrementAndGet() > limitFailure) {
   state = BreakerState.OPEN;
   TIMER.newTimeout(new TimerTask() {
      @Override
      public void run(Timeout timeout) throws Exception {
      state = BreakerState.HALF_OPEN;
      }
   }, timeout, TimeUnit.MILLISECONDS);
}

Demo: Suppose, i have cluster with 2 server (A, B) and Server A will invoke addProduct() to B by remote call. Here i will implement circuit-breaker on A to manage invoke remote call to B.

circuit-breaker3

+ AddProductCommand is extended BreakerCommand

public class AddProductCommand extends BreakerCommand{
   private static Logger LOGGER =    Logger.getLogger(AddProductCommand.class);
   private Product product;

   @Override
   public void run() {
      LOGGER.info("Process product "+product.getName());
   }
   public Product getProduct() {
      return product;
   }
   public void setProduct(Product product) {
      this.product = product;
   }

+ ProductService is extended BreakerExecute and add AddProductCommand to execute

public class ProductService extends BreakerExecute{
   private static Logger LOGGER =    Logger.getLogger(ProductService.class);

   --more--

   public void addProduct(Product product){
      AddProductCommand command = new AddProductCommand();
      command.setProduct(product);
      putCommand(command);
   }
   --more--
}

In the next post i will implement circuit-pattern by Golang. Please contact to me or comment into this below about your opinion about post, thank you for watching.

Get more project : source code

Leave a comment