1 package net.secodo.jcircuitbreaker.breakhandler.impl;
2
3 import java.util.Optional;
4 import java.util.concurrent.Callable;
5
6 import net.secodo.jcircuitbreaker.breaker.ContextAwareCircuitBreaker;
7 import net.secodo.jcircuitbreaker.breaker.execution.ExecutionContext;
8 import net.secodo.jcircuitbreaker.breakhandler.BreakHandler;
9 import net.secodo.jcircuitbreaker.breakhandler.exception.BreakHandlerException;
10 import net.secodo.jcircuitbreaker.breakstrategy.BreakStrategy;
11 import net.secodo.jcircuitbreaker.exception.TaskExecutionException;
12 import net.secodo.jcircuitbreaker.task.Task;
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 public class StatefulRetryHandler<R> implements BreakHandler<R> {
32 private final int maxNumberOfAttempts;
33 private final Optional<RetryHandlerOnRetryCallback<R>> onRetryCallback;
34
35 private int currentRetryAttempt;
36
37 public StatefulRetryHandler() {
38 this(1);
39 }
40
41 public StatefulRetryHandler(int maxNumberOfAttempts) {
42 this(maxNumberOfAttempts, null);
43 }
44
45 public StatefulRetryHandler(int maxNumberOfAttempts, RetryHandlerOnRetryCallback<R> onRetryCallback) {
46 this.maxNumberOfAttempts = maxNumberOfAttempts;
47 this.onRetryCallback = Optional.ofNullable(onRetryCallback);
48 }
49
50 @Override
51 public R onBreak(ContextAwareCircuitBreaker<R> circuitBreaker, Task<R> task, BreakStrategy<R> breakStrategy,
52 ExecutionContext<R> executionContext) throws TaskExecutionException, BreakHandlerException {
53 if (currentRetryAttempt == maxNumberOfAttempts) {
54 throw new RetryHandlerException(
55 "Number of retries reached maximum. Unable to execute the task: " + task + ". Max number of attempts was: " +
56 maxNumberOfAttempts);
57 }
58 currentRetryAttempt++;
59 onRetry(currentRetryAttempt, task, executionContext);
60
61 return circuitBreaker.executeInContext(task, breakStrategy, this, executionContext);
62
63 }
64
65 protected void onRetry(int currentRetryAttempt, Task<R> task, ExecutionContext<R> executionContext) {
66 if (onRetryCallback.isPresent()) {
67 onRetryCallback.get().onRetry(currentRetryAttempt, executionContext);
68 }
69 }
70
71 }