1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.named.support;
20
21 import java.util.concurrent.Callable;
22 import java.util.concurrent.TimeUnit;
23 import java.util.function.Predicate;
24
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28
29
30
31
32
33
34
35
36
37 public final class Retry {
38 private static final Logger LOGGER = LoggerFactory.getLogger(Retry.class);
39
40
41
42
43
44
45
46 public interface DoNotRetry {}
47
48 private Retry() {
49
50 }
51
52
53
54
55
56
57
58
59 public static <R> R retry(
60 final long time,
61 final TimeUnit unit,
62 final long sleepMillis,
63 final Callable<R> operation,
64 final Predicate<Exception> retryPredicate,
65 final R defaultResult)
66 throws InterruptedException {
67 long now = System.nanoTime();
68 final long barrier = now + unit.toNanos(time);
69 int attempt = 1;
70 R result = null;
71 while (now < barrier && result == null) {
72 try {
73 result = operation.call();
74 if (result == null) {
75 LOGGER.trace("Retry attempt {}: no result", attempt);
76 Thread.sleep(sleepMillis);
77 }
78 } catch (InterruptedException e) {
79 throw e;
80 } catch (Exception e) {
81 LOGGER.trace("Retry attempt {}: operation failure", attempt, e);
82 if (e instanceof DoNotRetry) {
83 if (e instanceof RuntimeException) {
84 throw (RuntimeException) e;
85 } else {
86 throw new IllegalStateException(e);
87 }
88 }
89 if (retryPredicate != null && !retryPredicate.test(e)) {
90 throw new IllegalStateException(e);
91 }
92 }
93 now = System.nanoTime();
94 attempt++;
95 }
96 return result == null ? defaultResult : result;
97 }
98
99
100
101
102
103
104
105
106
107
108
109 public static <R> R retry(
110 final int attempts,
111 final long sleepMillis,
112 final Callable<R> operation,
113 final Predicate<Exception> retryPredicate,
114 final R defaultResult)
115 throws InterruptedException {
116 int attempt = 1;
117 R result = null;
118 while (attempt <= attempts && result == null) {
119 try {
120 result = operation.call();
121 if (result == null) {
122 LOGGER.trace("Retry attempt {}: no result", attempt);
123 Thread.sleep(sleepMillis);
124 }
125 } catch (InterruptedException e) {
126 throw e;
127 } catch (Exception e) {
128 LOGGER.trace("Retry attempt {}: operation failure", attempt, e);
129 if (e instanceof DoNotRetry) {
130 if (e instanceof RuntimeException) {
131 throw (RuntimeException) e;
132 } else {
133 throw new IllegalStateException(e);
134 }
135 }
136 if (retryPredicate != null && !retryPredicate.test(e)) {
137 throw new IllegalStateException(e);
138 }
139 }
140 attempt++;
141 }
142 return result == null ? defaultResult : result;
143 }
144 }