18
18
*/
19
19
package io .github .resilience4j .retry ;
20
20
21
+ import java .util .concurrent .Callable ;
22
+ import java .util .function .Function ;
23
+ import java .util .function .Supplier ;
24
+
21
25
import io .github .resilience4j .core .EventConsumer ;
22
26
import io .github .resilience4j .retry .event .RetryEvent ;
23
27
import io .github .resilience4j .retry .event .RetryOnErrorEvent ;
29
33
import io .vavr .CheckedFunction1 ;
30
34
import io .vavr .CheckedRunnable ;
31
35
32
- import java .util .concurrent .Callable ;
33
- import java .util .function .Function ;
34
- import java .util .function .Supplier ;
35
-
36
36
/**
37
37
* A Retry instance is thread-safe can be used to decorate multiple requests.
38
38
* A Retry.
@@ -145,11 +145,15 @@ default void executeRunnable(Runnable runnable){
145
145
*/
146
146
static <T > CheckedFunction0 <T > decorateCheckedSupplier (Retry retry , CheckedFunction0 <T > supplier ){
147
147
return () -> {
148
- Retry .Context context = retry .context ();
148
+ @ SuppressWarnings ("unchecked" )
149
+ Retry .Context <T > context = retry .context ();
149
150
do try {
150
151
T result = supplier .apply ();
151
- context .onSuccess ();
152
- return result ;
152
+ final boolean validationOfResult = context .onResult (result );
153
+ if (!validationOfResult ) {
154
+ context .onSuccess ();
155
+ return result ;
156
+ }
153
157
} catch (Exception exception ) {
154
158
context .onError (exception );
155
159
} while (true );
@@ -189,11 +193,15 @@ static CheckedRunnable decorateCheckedRunnable(Retry retry, CheckedRunnable runn
189
193
*/
190
194
static <T , R > CheckedFunction1 <T , R > decorateCheckedFunction (Retry retry , CheckedFunction1 <T , R > function ){
191
195
return (T t ) -> {
192
- Retry .Context context = retry .context ();
196
+ @ SuppressWarnings ("unchecked" )
197
+ Retry .Context <R > context = retry .context ();
193
198
do try {
194
- R result = function .apply (t );
195
- context .onSuccess ();
196
- return result ;
199
+ R result = function .apply (t );
200
+ final boolean validationOfResult = context .onResult (result );
201
+ if (!validationOfResult ) {
202
+ context .onSuccess ();
203
+ return result ;
204
+ }
197
205
} catch (Exception exception ) {
198
206
context .onError (exception );
199
207
} while (true );
@@ -211,11 +219,15 @@ static <T, R> CheckedFunction1<T, R> decorateCheckedFunction(Retry retry, Checke
211
219
*/
212
220
static <T > Supplier <T > decorateSupplier (Retry retry , Supplier <T > supplier ){
213
221
return () -> {
214
- Retry .Context context = retry .context ();
222
+ @ SuppressWarnings ("unchecked" )
223
+ Retry .Context <T > context = retry .context ();
215
224
do try {
216
- T result = supplier .get ();
217
- context .onSuccess ();
218
- return result ;
225
+ T result = supplier .get ();
226
+ final boolean validationOfResult = context .onResult (result );
227
+ if (!validationOfResult ) {
228
+ context .onSuccess ();
229
+ return result ;
230
+ }
219
231
} catch (RuntimeException runtimeException ) {
220
232
context .onRuntimeError (runtimeException );
221
233
} while (true );
@@ -233,11 +245,15 @@ static <T> Supplier<T> decorateSupplier(Retry retry, Supplier<T> supplier){
233
245
*/
234
246
static <T > Callable <T > decorateCallable (Retry retry , Callable <T > supplier ){
235
247
return () -> {
236
- Retry .Context context = retry .context ();
248
+ @ SuppressWarnings ("unchecked" )
249
+ Retry .Context <T > context = retry .context ();
237
250
do try {
238
- T result = supplier .call ();
239
- context .onSuccess ();
240
- return result ;
251
+ T result = supplier .call ();
252
+ final boolean validationOfResult = context .onResult (result );
253
+ if (!validationOfResult ) {
254
+ context .onSuccess ();
255
+ return result ;
256
+ }
241
257
} catch (RuntimeException runtimeException ) {
242
258
context .onRuntimeError (runtimeException );
243
259
} while (true );
@@ -277,11 +293,15 @@ static Runnable decorateRunnable(Retry retry, Runnable runnable){
277
293
*/
278
294
static <T , R > Function <T , R > decorateFunction (Retry retry , Function <T , R > function ){
279
295
return (T t ) -> {
280
- Retry .Context context = retry .context ();
296
+ @ SuppressWarnings ("unchecked" )
297
+ Retry .Context <R > context = retry .context ();
281
298
do try {
282
- R result = function .apply (t );
283
- context .onSuccess ();
284
- return result ;
299
+ R result = function .apply (t );
300
+ final boolean validationOfResult = context .onResult (result );
301
+ if (!validationOfResult ) {
302
+ context .onSuccess ();
303
+ return result ;
304
+ }
285
305
} catch (RuntimeException runtimeException ) {
286
306
context .onRuntimeError (runtimeException );
287
307
} while (true );
@@ -326,13 +346,24 @@ interface Metrics {
326
346
long getNumberOfFailedCallsWithRetryAttempt ();
327
347
}
328
348
329
- interface Context {
349
+ /**
350
+ * the retry context which will be used during the retry iteration to decide what can be done on error , result, on runtime error
351
+ *
352
+ * @param <T> the result type
353
+ */
354
+ interface Context <T > {
330
355
331
356
/**
332
357
* Records a successful call.
333
358
*/
334
359
void onSuccess ();
335
360
361
+ /**
362
+ * @param result the returned result from the called logic
363
+ * @return true if we need to retry again or false if no retry anymore
364
+ */
365
+ boolean onResult (T result );
366
+
336
367
/**
337
368
* Handles a checked exception
338
369
*
0 commit comments