4343 */
4444public class FailsafeExecutor <R > extends PolicyListeners <FailsafeExecutor <R >, R > {
4545 private Scheduler scheduler = Scheduler .DEFAULT ;
46+ private Executor executor ;
4647 /** Policies sorted outer-most first */
4748 final List <? extends Policy <R >> policies ;
4849 private EventHandler <R > completeHandler ;
@@ -134,7 +135,7 @@ public <T extends R> T get(ContextualSupplier<T, T> supplier) {
134135 * @throws RejectedExecutionException if the {@code supplier} cannot be scheduled for execution
135136 */
136137 public <T extends R > CompletableFuture <T > getAsync (CheckedSupplier <T > supplier ) {
137- return callAsync (future -> getPromise (toCtxSupplier (supplier )), false );
138+ return callAsync (future -> getPromise (toCtxSupplier (supplier ), executor ), false );
138139 }
139140
140141 /**
@@ -153,7 +154,7 @@ public <T extends R> CompletableFuture<T> getAsync(CheckedSupplier<T> supplier)
153154 * @throws RejectedExecutionException if the {@code supplier} cannot be scheduled for execution
154155 */
155156 public <T extends R > CompletableFuture <T > getAsync (ContextualSupplier <T , T > supplier ) {
156- return callAsync (future -> getPromise (supplier ), false );
157+ return callAsync (future -> getPromise (supplier , executor ), false );
157158 }
158159
159160 /**
@@ -178,7 +179,7 @@ public <T extends R> CompletableFuture<T> getAsync(ContextualSupplier<T, T> supp
178179 * @throws RejectedExecutionException if the {@code supplier} cannot be scheduled for execution
179180 */
180181 public <T extends R > CompletableFuture <T > getAsyncExecution (AsyncRunnable <T > runnable ) {
181- return callAsync (future -> getPromiseExecution (runnable ), true );
182+ return callAsync (future -> getPromiseExecution (runnable , executor ), true );
182183 }
183184
184185 /**
@@ -199,7 +200,7 @@ public <T extends R> CompletableFuture<T> getAsyncExecution(AsyncRunnable<T> run
199200 * @throws RejectedExecutionException if the {@code supplier} cannot be scheduled for execution
200201 */
201202 public <T extends R > CompletableFuture <T > getStageAsync (CheckedSupplier <? extends CompletionStage <T >> supplier ) {
202- return callAsync (future -> getPromiseOfStage (toCtxSupplier (supplier ), future ), false );
203+ return callAsync (future -> getPromiseOfStage (toCtxSupplier (supplier ), future , executor ), false );
203204 }
204205
205206 /**
@@ -221,7 +222,7 @@ public <T extends R> CompletableFuture<T> getStageAsync(CheckedSupplier<? extend
221222 */
222223 public <T extends R > CompletableFuture <T > getStageAsync (
223224 ContextualSupplier <T , ? extends CompletionStage <T >> supplier ) {
224- return callAsync (future -> getPromiseOfStage (supplier , future ), false );
225+ return callAsync (future -> getPromiseOfStage (supplier , future , executor ), false );
225226 }
226227
227228 /**
@@ -249,7 +250,7 @@ public <T extends R> CompletableFuture<T> getStageAsync(
249250 */
250251 public <T extends R > CompletableFuture <T > getStageAsyncExecution (
251252 AsyncSupplier <T , ? extends CompletionStage <T >> supplier ) {
252- return callAsync (future -> getPromiseOfStageExecution (supplier , future ), true );
253+ return callAsync (future -> getPromiseOfStageExecution (supplier , future , executor ), true );
253254 }
254255
255256 /**
@@ -293,7 +294,7 @@ public void run(ContextualRunnable<Void> runnable) {
293294 * @throws RejectedExecutionException if the {@code runnable} cannot be scheduled for execution
294295 */
295296 public CompletableFuture <Void > runAsync (CheckedRunnable runnable ) {
296- return callAsync (future -> getPromise (toCtxSupplier (runnable )), false );
297+ return callAsync (future -> getPromise (toCtxSupplier (runnable ), executor ), false );
297298 }
298299
299300 /**
@@ -311,7 +312,7 @@ public CompletableFuture<Void> runAsync(CheckedRunnable runnable) {
311312 * @throws RejectedExecutionException if the {@code runnable} cannot be scheduled for execution
312313 */
313314 public CompletableFuture <Void > runAsync (ContextualRunnable <Void > runnable ) {
314- return callAsync (future -> getPromise (toCtxSupplier (runnable )), false );
315+ return callAsync (future -> getPromise (toCtxSupplier (runnable ), executor ), false );
315316 }
316317
317318 /**
@@ -336,7 +337,7 @@ public CompletableFuture<Void> runAsync(ContextualRunnable<Void> runnable) {
336337 * @throws RejectedExecutionException if the {@code runnable} cannot be scheduled for execution
337338 */
338339 public CompletableFuture <Void > runAsyncExecution (AsyncRunnable <Void > runnable ) {
339- return callAsync (future -> getPromiseExecution (runnable ), true );
340+ return callAsync (future -> getPromiseExecution (runnable , executor ), true );
340341 }
341342
342343 /**
@@ -372,33 +373,46 @@ public FailsafeExecutor<R> onSuccess(CheckedConsumer<ExecutionCompletedEvent<R>>
372373 }
373374
374375 /**
375- * Configures the {@code executor} to use for performing asynchronous executions and listener callbacks.
376+ * Configures the {@code scheduledExecutorService} to use for performing asynchronous executions and listener
377+ * callbacks.
376378 * <p>
377- * Note: The {@code executor } should have a core pool size of at least 2 in order for {@link Timeout timeouts} to
378- * work.
379+ * Note: The {@code scheduledExecutorService } should have a core pool size of at least 2 in order for {@link Timeout
380+ * timeouts} to work.
379381 * </p>
380382 *
381- * @throws NullPointerException if {@code executor } is null
382- * @throws IllegalArgumentException if the {@code executor } has a core pool size of less than 2
383+ * @throws NullPointerException if {@code scheduledExecutorService } is null
384+ * @throws IllegalArgumentException if the {@code scheduledExecutorService } has a core pool size of less than 2
383385 */
384- public FailsafeExecutor <R > with (ScheduledExecutorService executor ) {
385- this .scheduler = Scheduler .of (executor );
386+ public FailsafeExecutor <R > with (ScheduledExecutorService scheduledExecutorService ) {
387+ this .scheduler = Scheduler .of (Assert . notNull ( scheduledExecutorService , "scheduledExecutorService" ) );
386388 return this ;
387389 }
388390
389391 /**
390- * Configures the {@code executor } to use for performing asynchronous executions and listener callbacks. For
391- * executions that require a delay, an internal ScheduledExecutorService will be used for the delay, then the {@code
392- * executor } will be used for actual execution.
392+ * Configures the {@code executorService } to use for performing asynchronous executions and listener callbacks. For
393+ * async executions that require a delay, an internal ScheduledExecutorService will be used for the delay, then the
394+ * {@code executorService } will be used for actual execution.
393395 * <p>
394- * Note: The {@code executor } should have a core pool size or parallelism of at least 2 in order for {@link Timeout
395- * timeouts} to work.
396+ * Note: The {@code executorService } should have a core pool size or parallelism of at least 2 in order for {@link
397+ * Timeout timeouts} to work.
396398 * </p>
397399 *
400+ * @throws NullPointerException if {@code executorService} is null
401+ */
402+ public FailsafeExecutor <R > with (ExecutorService executorService ) {
403+ this .scheduler = Scheduler .of (Assert .notNull (executorService , "executorService" ));
404+ return this ;
405+ }
406+
407+ /**
408+ * Configures the {@code executor} to use as a wrapper around executions. The {@code executor} is responsible for
409+ * propagating executions. Executions that normally return a result, such as {@link #get(CheckedSupplier)} will return
410+ * {@code null} since the {@link Executor} interface does not support results.
411+ *
398412 * @throws NullPointerException if {@code executor} is null
399413 */
400414 public FailsafeExecutor <R > with (Executor executor ) {
401- this .scheduler = Scheduler . of (executor );
415+ this .executor = Assert . notNull (executor , "executor" );
402416 return this ;
403417 }
404418
@@ -422,7 +436,7 @@ public FailsafeExecutor<R> with(Scheduler scheduler) {
422436 */
423437 @ SuppressWarnings ({ "unchecked" , "rawtypes" })
424438 private <T > T call (ContextualSupplier <T , T > innerSupplier ) {
425- SyncExecutionImpl <T > execution = new SyncExecutionImpl (this , scheduler , Functions .get (innerSupplier ));
439+ SyncExecutionImpl <T > execution = new SyncExecutionImpl (this , scheduler , Functions .get (innerSupplier , executor ));
426440 ExecutionResult <T > result = execution .executeSync ();
427441 Throwable failure = result .getFailure ();
428442 if (failure != null ) {
0 commit comments