| 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 2.2 3.3 |
|
| 71 |
1.1 |
|
| 72 |
1.1 |
|
| 76 |
1.1 |
|
| 80 |
1.1 |
|
| 84 |
1.1 |
|
| 88 |
1.1 2.2 |
|
| 89 |
1.1 2.2 |
|
| 92 |
1.1 |
|
| 93 |
1.1 |