From 9137eed4266f5cb3dd05b9165ccfd068912cccf0 Mon Sep 17 00:00:00 2001 From: WhatCats Date: Wed, 28 May 2025 15:18:51 +0200 Subject: [PATCH] respect executors that can't schedule --- .../tommyjs/futur/executor/ExecutorImpl.java | 5 +- .../futur/executor/ExecutorServiceImpl.java | 5 +- .../futur/executor/PromiseExecutor.java | 3 +- .../futur/promise/AbstractPromise.java | 58 +++++++++++++------ 4 files changed, 47 insertions(+), 24 deletions(-) diff --git a/futur-api/src/main/java/dev/tommyjs/futur/executor/ExecutorImpl.java b/futur-api/src/main/java/dev/tommyjs/futur/executor/ExecutorImpl.java index dbed16d..0e0da40 100644 --- a/futur-api/src/main/java/dev/tommyjs/futur/executor/ExecutorImpl.java +++ b/futur-api/src/main/java/dev/tommyjs/futur/executor/ExecutorImpl.java @@ -1,6 +1,7 @@ package dev.tommyjs.futur.executor; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.concurrent.Executor; @@ -24,8 +25,8 @@ class ExecutorImpl implements PromiseExecutor { } @Override - public @NotNull PromiseScheduler scheduler() { - return PromiseScheduler.getDefault(); + public @Nullable PromiseScheduler scheduler() { + return null; } } diff --git a/futur-api/src/main/java/dev/tommyjs/futur/executor/ExecutorServiceImpl.java b/futur-api/src/main/java/dev/tommyjs/futur/executor/ExecutorServiceImpl.java index 98867fb..975bace 100644 --- a/futur-api/src/main/java/dev/tommyjs/futur/executor/ExecutorServiceImpl.java +++ b/futur-api/src/main/java/dev/tommyjs/futur/executor/ExecutorServiceImpl.java @@ -1,6 +1,7 @@ package dev.tommyjs.futur.executor; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; @@ -24,8 +25,8 @@ class ExecutorServiceImpl implements PromiseExecutor> { } @Override - public @NotNull PromiseScheduler scheduler() { - return PromiseScheduler.getDefault(); + public @Nullable PromiseScheduler scheduler() { + return null; } } diff --git a/futur-api/src/main/java/dev/tommyjs/futur/executor/PromiseExecutor.java b/futur-api/src/main/java/dev/tommyjs/futur/executor/PromiseExecutor.java index 8389e19..c883fb3 100644 --- a/futur-api/src/main/java/dev/tommyjs/futur/executor/PromiseExecutor.java +++ b/futur-api/src/main/java/dev/tommyjs/futur/executor/PromiseExecutor.java @@ -1,6 +1,7 @@ package dev.tommyjs.futur.executor; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -77,6 +78,6 @@ public interface PromiseExecutor { */ boolean cancel(@NotNull T task); - @NotNull PromiseScheduler scheduler(); + @Nullable PromiseScheduler scheduler(); } diff --git a/futur-api/src/main/java/dev/tommyjs/futur/promise/AbstractPromise.java b/futur-api/src/main/java/dev/tommyjs/futur/promise/AbstractPromise.java index 2ff169e..620af47 100644 --- a/futur-api/src/main/java/dev/tommyjs/futur/promise/AbstractPromise.java +++ b/futur-api/src/main/java/dev/tommyjs/futur/promise/AbstractPromise.java @@ -215,9 +215,8 @@ public abstract class AbstractPromise implements Promise { CompletablePromise promise = createLinked(); addDirectListener( res -> runCompleter(promise, () -> { - Runnable runnable = createCompleter(res, promise, task); - F future = executor.run(runnable); - promise.addDirectListener(_ -> executor.cancel(future)); + Runnable completer = createCompleter(res, promise, task); + execute(promise, completer, executor); }), promise::completeExceptionally ); @@ -227,14 +226,22 @@ public abstract class AbstractPromise implements Promise { private @NotNull Promise thenApplyDelayed( @NotNull ExceptionalFunction task, long delay, - @NotNull TimeUnit unit, @NotNull PromiseScheduler scheduler + @NotNull TimeUnit unit, @NotNull PromiseExecutor executor ) { CompletablePromise promise = createLinked(); addDirectListener( res -> runCompleter(promise, () -> { - Runnable runnable = createCompleter(res, promise, task); - F future = scheduler.schedule(runnable, delay, unit); - promise.addDirectListener(_ -> scheduler.cancel(future)); + Runnable completer = createCompleter(res, promise, task); + PromiseScheduler scheduler = executor.scheduler(); + if (scheduler == null) { + schedule( + promise, + () -> runCompleter(promise, () -> execute(promise, completer, executor)), + delay, unit, PromiseScheduler.getDefault() + ); + } else { + schedule(promise, completer, delay, unit, scheduler); + } }), promise::completeExceptionally ); @@ -242,6 +249,19 @@ public abstract class AbstractPromise implements Promise { return promise; } + private void execute(@NotNull Promise promise, @NotNull Runnable task, @NotNull PromiseExecutorexecutor) throws Exception { + F future = executor.run(task); + promise.addDirectListener(_ -> executor.cancel(future)); + } + + private void schedule( + @NotNull Promise promise, @NotNull Runnable task, + long delay, @NotNull TimeUnit unit, @NotNull PromiseScheduler scheduler + ) throws Exception { + F future = scheduler.schedule(task, delay, unit); + promise.addDirectListener(_ -> scheduler.cancel(future)); + } + private @NotNull Promise thenCompose( @NotNull ExceptionalFunction> task, @NotNull PromiseExecutor executor @@ -269,7 +289,7 @@ public abstract class AbstractPromise implements Promise { @Override public @NotNull Promise thenRunDelayedSync(@NotNull ExceptionalRunnable task, long delay, @NotNull TimeUnit unit) { - return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getSyncExecutor().scheduler()); + return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getSyncExecutor()); } @Override @@ -279,7 +299,7 @@ public abstract class AbstractPromise implements Promise { @Override public @NotNull Promise thenConsumeDelayedSync(@NotNull ExceptionalConsumer task, long delay, @NotNull TimeUnit unit) { - return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getSyncExecutor().scheduler()); + return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getSyncExecutor()); } @Override @@ -289,7 +309,7 @@ public abstract class AbstractPromise implements Promise { @Override public @NotNull Promise thenSupplyDelayedSync(@NotNull ExceptionalSupplier task, long delay, @NotNull TimeUnit unit) { - return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getSyncExecutor().scheduler()); + return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getSyncExecutor()); } @Override @@ -299,7 +319,7 @@ public abstract class AbstractPromise implements Promise { @Override public @NotNull Promise thenApplyDelayedSync(@NotNull ExceptionalFunction task, long delay, @NotNull TimeUnit unit) { - return thenApplyDelayed(task, delay, unit, getFactory().getSyncExecutor().scheduler()); + return thenApplyDelayed(task, delay, unit, getFactory().getSyncExecutor()); } @Override @@ -314,7 +334,7 @@ public abstract class AbstractPromise implements Promise { @Override public @NotNull Promise thenRunDelayedAsync(@NotNull ExceptionalRunnable task, long delay, @NotNull TimeUnit unit) { - return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getAsyncExecutor().scheduler()); + return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getAsyncExecutor()); } @Override @@ -324,7 +344,7 @@ public abstract class AbstractPromise implements Promise { @Override public @NotNull Promise thenConsumeDelayedAsync(@NotNull ExceptionalConsumer task, long delay, @NotNull TimeUnit unit) { - return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getAsyncExecutor().scheduler()); + return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getAsyncExecutor()); } @Override @@ -334,7 +354,7 @@ public abstract class AbstractPromise implements Promise { @Override public @NotNull Promise thenSupplyDelayedAsync(@NotNull ExceptionalSupplier task, long delay, @NotNull TimeUnit unit) { - return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getAsyncExecutor().scheduler()); + return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getAsyncExecutor()); } @Override @@ -344,7 +364,7 @@ public abstract class AbstractPromise implements Promise { @Override public @NotNull Promise thenApplyDelayedAsync(@NotNull ExceptionalFunction task, long delay, @NotNull TimeUnit unit) { - return thenApplyDelayed(task, delay, unit, getFactory().getAsyncExecutor().scheduler()); + return thenApplyDelayed(task, delay, unit, getFactory().getAsyncExecutor()); } @Override @@ -359,7 +379,7 @@ public abstract class AbstractPromise implements Promise { @Override public @NotNull Promise thenRunDelayedVirtual(@NotNull ExceptionalRunnable task, long delay, @NotNull TimeUnit unit) { - return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getVirtualExecutor().scheduler()); + return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getVirtualExecutor()); } @Override @@ -369,7 +389,7 @@ public abstract class AbstractPromise implements Promise { @Override public @NotNull Promise thenConsumeDelayedVirtual(@NotNull ExceptionalConsumer task, long delay, @NotNull TimeUnit unit) { - return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getVirtualExecutor().scheduler()); + return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getVirtualExecutor()); } @Override @@ -379,7 +399,7 @@ public abstract class AbstractPromise implements Promise { @Override public @NotNull Promise thenSupplyDelayedVirtual(@NotNull ExceptionalSupplier task, long delay, @NotNull TimeUnit unit) { - return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getVirtualExecutor().scheduler()); + return thenApplyDelayed(FunctionAdapter.adapt(task), delay, unit, getFactory().getVirtualExecutor()); } @Override @@ -389,7 +409,7 @@ public abstract class AbstractPromise implements Promise { @Override public @NotNull Promise thenApplyDelayedVirtual(@NotNull ExceptionalFunction task, long delay, @NotNull TimeUnit unit) { - return thenApplyDelayed(task, delay, unit, getFactory().getVirtualExecutor().scheduler()); + return thenApplyDelayed(task, delay, unit, getFactory().getVirtualExecutor()); } @Override