ReusableRetryHandler.java

package net.secodo.jcircuitbreaker.breakhandler.impl;

import java.util.concurrent.Callable;

import net.secodo.jcircuitbreaker.breaker.CircuitBreaker;
import net.secodo.jcircuitbreaker.breaker.execution.ExecutionContext;
import net.secodo.jcircuitbreaker.breakhandler.BreakHandler;
import net.secodo.jcircuitbreaker.breakhandler.OnePerExecutionHandlerFactory;
import net.secodo.jcircuitbreaker.breakhandler.helper.InstantiationHelper;
import net.secodo.jcircuitbreaker.task.Task;


/**
 * An implementation of {@link BreakHandler} which creates single instance of {@link StatefulRetryHandler} per
 * execution context. Created instance is later reused for handling subsequent retry calls in current execution context.
 *
 * <p>The instance is bound to current ExecutionContext. This means that "one and only one" instance of
 * {@link StatefulRetryHandler} will be crated per execution of a Task, no matter how many times circuit breaker will
 * try to call <i>target method</i> again.
 *
 * @param <R> the return type of produced {@link StatefulRetryHandler} which equals to the return type of
 *           <i>target-method</i> which is executed by circuit breaker.
 */
public class ReusableRetryHandler<R> implements OnePerExecutionHandlerFactory<R> {
  private static final String EXECUTION_CONTEXT_PARAM_NAME = ReusableRetryHandler.class.getSimpleName() +
    "_created_handler";

  private final int maxNumberOfAttempts;

  public ReusableRetryHandler(int maxNumberOfAttempts) {
    this.maxNumberOfAttempts = maxNumberOfAttempts;
  }

  @Override
  public BreakHandler<R> createNewHandler(Task<R> task, ExecutionContext<R> executionContext) {
    // NOTE: below instruction could be replaced with: 'return new StatefulRetryHandler<>(maxNumberOfAttempts);
    return InstantiationHelper.constructSingleParamInstance(StatefulRetryHandler.class, maxNumberOfAttempts);
  }

  @Override
  public String getOnePerExecutionContextParamName(Task<R> task, ExecutionContext<R> executionContext) {
    return EXECUTION_CONTEXT_PARAM_NAME;
  }
}