Avoid blocking worker pool for command timeout check (#2951)

3rd time lucky...
This commit is contained in:
Luck 2021-03-24 12:40:24 +00:00
parent f0e1a8f092
commit 2e62c98c45
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
2 changed files with 5 additions and 43 deletions

View File

@ -182,7 +182,11 @@ public class CommandManager {
}, this.executor);
// schedule another task to catch if the command doesn't complete after 10 seconds
timeoutTask.set(scheduler.awaitTimeout(future, 10, TimeUnit.SECONDS, () -> handleCommandTimeout(executorThread, argsCopy)));
timeoutTask.set(scheduler.asyncLater(() -> {
if (!future.isDone()) {
handleCommandTimeout(executorThread, argsCopy);
}
}, 10, TimeUnit.SECONDS));
return future;
}

View File

@ -25,12 +25,8 @@
package me.lucko.luckperms.common.plugin.scheduler;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
/**
* A scheduler for running tasks using the systems provided by the platform
@ -89,44 +85,6 @@ public interface SchedulerAdapter {
*/
SchedulerTask asyncRepeating(Runnable task, long interval, TimeUnit unit);
/**
* Waits for the given time for {@code future} to complete. If the future isn't completed,
* {@code onTimeout} is executed.
*
* @param future the future to wait for
* @param timeout the time to wait
* @param unit the unit of timeout
* @param onTimeout the function to execute when the timeout expires
*/
default SchedulerTask awaitTimeout(CompletableFuture<?> future, long timeout, TimeUnit unit, Runnable onTimeout) {
// a reference to the thread blocking on the future
AtomicReference<Thread> thread = new AtomicReference<>();
// in a new thread, await the completion of the future up to the given timeout
executeAsync(() -> {
thread.set(Thread.currentThread());
try {
future.get(timeout, unit);
} catch (InterruptedException | ExecutionException e) {
// ignore - this probably means the future completed successfully!
} catch (TimeoutException e) {
// run the timeout task
onTimeout.run();
} finally {
thread.set(null);
}
});
// to cancel the timeout task, just interrupt the thread that is blocking on the future
// and it will gracefully stop.
return () -> {
Thread t;
if ((t = thread.get()) != null) {
t.interrupt();
}
};
}
/**
* Shuts down the scheduler instance.
*