18
18
import net .jodah .failsafe .util .concurrent .Scheduler ;
19
19
20
20
import java .util .concurrent .*;
21
+ import java .util .function .Supplier ;
21
22
22
23
/**
23
24
* A PolicyExecutor that handles failures according to a {@link Fallback}.
@@ -27,47 +28,68 @@ class FallbackExecutor extends PolicyExecutor<Fallback> {
27
28
super (fallback , execution );
28
29
}
29
30
31
+ /**
32
+ * Performs an execution by calling pre-execute else calling the supplier, applying a fallback if it fails, and
33
+ * calling post-execute.
34
+ */
30
35
@ Override
31
36
@ SuppressWarnings ("unchecked" )
32
- protected ExecutionResult onFailure (ExecutionResult result ) {
33
- try {
34
- return policy == Fallback .VOID ?
35
- result .withNonResult () :
36
- result .withResult (policy .apply (result .getResult (), result .getFailure (), execution .copy ()));
37
- } catch (Throwable t ) {
38
- return ExecutionResult .failure (t );
39
- }
37
+ protected Supplier <ExecutionResult > supply (Supplier <ExecutionResult > supplier , Scheduler scheduler ) {
38
+ return () -> {
39
+ ExecutionResult result = supplier .get ();
40
+ if (isFailure (result )) {
41
+ try {
42
+ result = policy == Fallback .VOID ?
43
+ result .withNonResult () :
44
+ result .withResult (policy .apply (result .getResult (), result .getFailure (), execution .copy ()));
45
+ } catch (Throwable t ) {
46
+ result = ExecutionResult .failure (t );
47
+ }
48
+ }
49
+
50
+ return postExecute (result );
51
+ };
40
52
}
41
53
54
+ /**
55
+ * Performs an async execution by calling pre-execute else calling the supplier and doing a post-execute.
56
+ */
57
+ @ Override
42
58
@ SuppressWarnings ("unchecked" )
43
- protected CompletableFuture <ExecutionResult > onFailureAsync (ExecutionResult result , Scheduler scheduler ,
44
- FailsafeFuture <Object > future ) {
45
- CompletableFuture <ExecutionResult > promise = new CompletableFuture <>();
46
- Callable <Object > callable = () -> {
47
- try {
48
- CompletableFuture <Object > fallback = policy .applyStage (result .getResult (), result .getFailure (),
49
- execution .copy ());
50
- fallback .whenComplete ((innerResult , failure ) -> {
51
- if (failure instanceof CompletionException )
52
- failure = failure .getCause ();
53
- ExecutionResult r = failure == null ? result .withResult (innerResult ) : ExecutionResult .failure (failure );
54
- promise .complete (r );
55
- });
56
- } catch (Throwable t ) {
57
- promise .complete (ExecutionResult .failure (t ));
58
- }
59
- return null ;
60
- };
59
+ protected Supplier <CompletableFuture <ExecutionResult >> supplyAsync (
60
+ Supplier <CompletableFuture <ExecutionResult >> supplier , Scheduler scheduler , FailsafeFuture <Object > future ) {
61
+ return () -> supplier .get ().thenCompose (result -> {
62
+ if (isFailure (result )) {
63
+ CompletableFuture <ExecutionResult > promise = new CompletableFuture <>();
64
+ Callable <Object > callable = () -> {
65
+ try {
66
+ CompletableFuture <Object > fallback = policy .applyStage (result .getResult (), result .getFailure (),
67
+ execution .copy ());
68
+ fallback .whenComplete ((innerResult , failure ) -> {
69
+ if (failure instanceof CompletionException )
70
+ failure = failure .getCause ();
71
+ ExecutionResult r = failure == null ? result .withResult (innerResult ) : ExecutionResult .failure (failure );
72
+ promise .complete (r );
73
+ });
74
+ } catch (Throwable t ) {
75
+ promise .complete (ExecutionResult .failure (t ));
76
+ }
77
+ return null ;
78
+ };
61
79
62
- try {
63
- if (!policy .isAsync ())
64
- callable .call ();
65
- else
66
- future .inject ((Future ) scheduler .schedule (callable , result .getWaitNanos (), TimeUnit .NANOSECONDS ));
67
- } catch (Throwable t ) {
68
- promise .completeExceptionally (t );
69
- }
80
+ try {
81
+ if (!policy .isAsync ())
82
+ callable .call ();
83
+ else
84
+ future .inject ((Future ) scheduler .schedule (callable , result .getWaitNanos (), TimeUnit .NANOSECONDS ));
85
+ } catch (Throwable t ) {
86
+ promise .completeExceptionally (t );
87
+ }
88
+
89
+ return promise .thenCompose (ss -> postExecuteAsync (ss , scheduler , future ));
90
+ }
70
91
71
- return promise ;
92
+ return postExecuteAsync (result , scheduler , future );
93
+ });
72
94
}
73
95
}
0 commit comments