1818import net .jodah .failsafe .util .concurrent .Scheduler ;
1919
2020import java .util .concurrent .*;
21+ import java .util .function .Supplier ;
2122
2223/**
2324 * A PolicyExecutor that handles failures according to a {@link Fallback}.
@@ -27,47 +28,68 @@ class FallbackExecutor extends PolicyExecutor<Fallback> {
2728 super (fallback , execution );
2829 }
2930
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+ */
3035 @ Override
3136 @ 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+ };
4052 }
4153
54+ /**
55+ * Performs an async execution by calling pre-execute else calling the supplier and doing a post-execute.
56+ */
57+ @ Override
4258 @ 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+ };
6179
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+ }
7091
71- return promise ;
92+ return postExecuteAsync (result , scheduler , future );
93+ });
7294 }
7395}
0 commit comments