PerExecutionDelayRetry.java

1
package fr.sii.ogham.core.retry;
2
3
import java.time.Instant;
4
import java.util.List;
5
6
/**
7
 * Retry several times with a fixed delay to wait after the last execution
8
 * failure until the maximum attempts is reached. A specific delay is used
9
 * between each execution. If there are more attempts than the configured
10
 * delays, the last delay is used for remaining attempts.
11
 * 
12
 * If maximum attempts are set to 5 and delays are configured like this:
13
 * <ol>
14
 * <li>500ms</li>
15
 * <li>750ms</li>
16
 * <li>1800ms</li>
17
 * </ol>
18
 * 
19
 * If the action (named "connect" for the example) takes 100ms to execute before
20
 * failing, here is what happens:
21
 * 
22
 * <ul>
23
 * <li>0: connect</li>
24
 * <li>100: timeout</li>
25
 * <li>600: connect</li>
26
 * <li>700: timeout</li>
27
 * <li>1450: connect</li>
28
 * <li>1550: timeout</li>
29
 * <li>3350: connect</li>
30
 * <li>3450: timeout</li>
31
 * <li>5250: connect</li>
32
 * <li>5350: timeout</li>
33
 * <li>7150: connect</li>
34
 * <li>7250: timeout</li>
35
 * <li>fail</li>
36
 * </ul>
37
 * 
38
 * 
39
 * @author Aurélien Baudet
40
 *
41
 */
42
public class PerExecutionDelayRetry implements RetryStrategy {
43
	private final int maxRetries;
44
	private final List<Long> delays;
45
	private int retries;
46
	private int delayIdx;
47
48
	/**
49
	 * Initializes with the maximum attempts and the delays to wait after a
50
	 * failure.
51
	 * 
52
	 * @param maxRetries
53
	 *            the maximum attempts
54
	 * @param delays
55
	 *            the delays to wait after failure to do another attempt
56
	 */
57
	public PerExecutionDelayRetry(int maxRetries, List<Long> delays) {
58
		super();
59
		this.maxRetries = maxRetries;
60
		this.delays = delays;
61
		retries = maxRetries;
62
	}
63
64
	@Override
65
	public boolean terminated() {
66 3 1. terminated : changed conditional boundary → RUN_ERROR
2. terminated : negated conditional → RUN_ERROR
3. terminated : replaced boolean return with true for fr/sii/ogham/core/retry/PerExecutionDelayRetry::terminated → RUN_ERROR
		return retries <= 0;
67
	}
68
69
	@Override
70
	public Instant nextDate(Instant executionStartTime, Instant executionFailureTime) {
71 1 1. nextDate : Replaced integer subtraction with addition → RUN_ERROR
		retries--;
72 1 1. nextDate : replaced return value with null for fr/sii/ogham/core/retry/PerExecutionDelayRetry::nextDate → RUN_ERROR
		return executionFailureTime.plusMillis(getNextDelay());
73
	}
74
75
	public int getRemainingRetries() {
76 1 1. getRemainingRetries : replaced int return with 0 for fr/sii/ogham/core/retry/PerExecutionDelayRetry::getRemainingRetries → RUN_ERROR
		return retries;
77
	}
78
79
	public int getMaxRetries() {
80 1 1. getMaxRetries : replaced int return with 0 for fr/sii/ogham/core/retry/PerExecutionDelayRetry::getMaxRetries → NO_COVERAGE
		return maxRetries;
81
	}
82
83
	public List<Long> getDelays() {
84 1 1. getDelays : replaced return value with Collections.emptyList for fr/sii/ogham/core/retry/PerExecutionDelayRetry::getDelays → NO_COVERAGE
		return delays;
85
	}
86
87
	private long getNextDelay() {
88 2 1. getNextDelay : changed conditional boundary → RUN_ERROR
2. getNextDelay : negated conditional → RUN_ERROR
		if (delayIdx >= delays.size()) {
89 2 1. getNextDelay : Replaced integer subtraction with addition → RUN_ERROR
2. getNextDelay : replaced long return with 0 for fr/sii/ogham/core/retry/PerExecutionDelayRetry::getNextDelay → RUN_ERROR
			return delays.get(delays.size() - 1);
90
		}
91
		long delay = delays.get(delayIdx);
92 1 1. getNextDelay : Replaced integer addition with subtraction → RUN_ERROR
		delayIdx++;
93 1 1. getNextDelay : replaced long return with 0 for fr/sii/ogham/core/retry/PerExecutionDelayRetry::getNextDelay → RUN_ERROR
		return delay;
94
	}
95
}

Mutations

66

1.1
Location : terminated
Killed by :
changed conditional boundary → RUN_ERROR

2.2
Location : terminated
Killed by :
negated conditional → RUN_ERROR

3.3
Location : terminated
Killed by :
replaced boolean return with true for fr/sii/ogham/core/retry/PerExecutionDelayRetry::terminated → RUN_ERROR

71

1.1
Location : nextDate
Killed by :
Replaced integer subtraction with addition → RUN_ERROR

72

1.1
Location : nextDate
Killed by :
replaced return value with null for fr/sii/ogham/core/retry/PerExecutionDelayRetry::nextDate → RUN_ERROR

76

1.1
Location : getRemainingRetries
Killed by :
replaced int return with 0 for fr/sii/ogham/core/retry/PerExecutionDelayRetry::getRemainingRetries → RUN_ERROR

80

1.1
Location : getMaxRetries
Killed by :
replaced int return with 0 for fr/sii/ogham/core/retry/PerExecutionDelayRetry::getMaxRetries → NO_COVERAGE

84

1.1
Location : getDelays
Killed by :
replaced return value with Collections.emptyList for fr/sii/ogham/core/retry/PerExecutionDelayRetry::getDelays → NO_COVERAGE

88

1.1
Location : getNextDelay
Killed by :
changed conditional boundary → RUN_ERROR

2.2
Location : getNextDelay
Killed by :
negated conditional → RUN_ERROR

89

1.1
Location : getNextDelay
Killed by :
Replaced integer subtraction with addition → RUN_ERROR

2.2
Location : getNextDelay
Killed by :
replaced long return with 0 for fr/sii/ogham/core/retry/PerExecutionDelayRetry::getNextDelay → RUN_ERROR

92

1.1
Location : getNextDelay
Killed by :
Replaced integer addition with subtraction → RUN_ERROR

93

1.1
Location : getNextDelay
Killed by :
replaced long return with 0 for fr/sii/ogham/core/retry/PerExecutionDelayRetry::getNextDelay → RUN_ERROR

Active mutators

Tests examined


Report generated by PIT 1.13.1