View Javadoc
1   package net.secodo.jcircuitbreaker.breakhandler.impl;
2   
3   import java.util.concurrent.Callable;
4   
5   import net.secodo.jcircuitbreaker.breaker.CircuitBreaker;
6   import net.secodo.jcircuitbreaker.breaker.execution.ExecutionContext;
7   import net.secodo.jcircuitbreaker.breakhandler.BreakHandler;
8   import net.secodo.jcircuitbreaker.breakhandler.OnePerExecutionHandlerFactory;
9   import net.secodo.jcircuitbreaker.breakhandler.helper.InstantiationHelper;
10  import net.secodo.jcircuitbreaker.task.Task;
11  
12  
13  /**
14   * An implementation of {@link BreakHandler} which creates single instance of {@link StatefulRetryHandler} per
15   * execution context. Created instance is later reused for handling subsequent retry calls in current execution context.
16   *
17   * <p>The instance is bound to current ExecutionContext. This means that "one and only one" instance of
18   * {@link StatefulRetryHandler} will be crated per execution of a Task, no matter how many times circuit breaker will
19   * try to call <i>target method</i> again.
20   *
21   * @param <R> the return type of produced {@link StatefulRetryHandler} which equals to the return type of
22   *           <i>target-method</i> which is executed by circuit breaker.
23   */
24  public class ReusableRetryHandler<R> implements OnePerExecutionHandlerFactory<R> {
25    private static final String EXECUTION_CONTEXT_PARAM_NAME = ReusableRetryHandler.class.getSimpleName() +
26      "_created_handler";
27  
28    private final int maxNumberOfAttempts;
29  
30    public ReusableRetryHandler(int maxNumberOfAttempts) {
31      this.maxNumberOfAttempts = maxNumberOfAttempts;
32    }
33  
34    @Override
35    public BreakHandler<R> createNewHandler(Task<R> task, ExecutionContext<R> executionContext) {
36      // NOTE: below instruction could be replaced with: 'return new StatefulRetryHandler<>(maxNumberOfAttempts);
37      return InstantiationHelper.constructSingleParamInstance(StatefulRetryHandler.class, maxNumberOfAttempts);
38    }
39  
40    @Override
41    public String getOnePerExecutionContextParamName(Task<R> task, ExecutionContext<R> executionContext) {
42      return EXECUTION_CONTEXT_PARAM_NAME;
43    }
44  }