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;
}
}