Switch to KeySequentialExecutor

Use https://github.com/jano7/executor
This commit is contained in:
Gabriele C 2020-11-25 18:59:50 +01:00
parent 8a126858a7
commit d8c09ab6d1
2 changed files with 19 additions and 52 deletions

12
pom.xml
View File

@ -308,6 +308,10 @@
<pattern>ch.jalu</pattern>
<shadedPattern>fr.xephi.authme.libs.ch.jalu</shadedPattern>
</relocation>
<relocation>
<pattern>com.jano7.executor</pattern>
<shadedPattern>fr.xephi.authme.libs.com.jano7.executor</shadedPattern>
</relocation>
<relocation>
<pattern>com.zaxxer.hikari</pattern>
<shadedPattern>fr.xephi.authme.libs.com.zaxxer.hikari</shadedPattern>
@ -556,6 +560,14 @@
<scope>provided</scope>
</dependency>
<!-- Key Sequential Executor for async tasks -->
<dependency>
<groupId>com.jano7</groupId>
<artifactId>executor</artifactId>
<version>2.0.2</version>
<optional>true</optional>
</dependency>
<!-- Database Connection Pool -->
<dependency>
<groupId>com.zaxxer</groupId>

View File

@ -1,15 +1,10 @@
package fr.xephi.authme.process;
import com.jano7.executor.KeySequentialRunner;
import fr.xephi.authme.service.BukkitService;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import javax.inject.Inject;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Function;
/**
* Handles the queue of async tasks on a per-player basis.
@ -19,74 +14,34 @@ public class AsyncUserScheduler {
@Inject
private BukkitService bukkitService;
private KeyedSequentialScheduler<String> asyncUserScheduler;
private KeySequentialRunner<String> asyncUserScheduler;
AsyncUserScheduler() {
this.asyncUserScheduler = new KeyedSequentialScheduler<>(runnable ->
bukkitService.runTaskAsynchronously(runnable));
this.asyncUserScheduler = new KeySequentialRunner<>(command -> bukkitService.runTaskAsynchronously(command));
}
/**
* Adds a task to the player's async task queue.
*
* @param playerName the player name.
* @param runnable the task.
* @param runnable the task.
*/
public void runTask(String playerName, Runnable runnable) {
if (bukkitService.isUseAsyncTasks()) {
asyncUserScheduler.submit(playerName.toLowerCase(), runnable);
asyncUserScheduler.run(playerName.toLowerCase(), runnable);
} else {
runnable.run();
}
}
/**
* Adds a task to the player's async task queue.
*
* @param player the player.
* @param player the player.
* @param runnable the task.
*/
public void runTask(Player player, Runnable runnable) {
runTask(player.getName(), runnable);
}
public class KeyedSequentialScheduler<K> {
private Map<K, SequentialExecutor> executors;
private Function<Runnable, BukkitTask> scheduler;
public KeyedSequentialScheduler(Function<Runnable, BukkitTask> scheduler) {
this.executors = new LinkedHashMap<>();
this.scheduler = scheduler;
}
public void submit(K key, Runnable runnable) {
executors.computeIfAbsent(key, k -> new SequentialExecutor(scheduler, () -> executors.remove(key)))
.submit(runnable);
}
}
public class SequentialExecutor {
private Queue<Runnable> queue;
private Function<Runnable, BukkitTask> scheduler;
private Runnable callback;
private BukkitTask executor;
public SequentialExecutor(Function<Runnable, BukkitTask> scheduler, Runnable callback) {
this.queue = new LinkedBlockingQueue<>();
this.scheduler = scheduler;
this.callback = callback;
}
public void submit(Runnable task) {
queue.add(task);
if (executor == null || executor.isCancelled()) {
executor = scheduler.apply(() -> {
while (!queue.isEmpty()) {
queue.poll().run();
}
callback.run();
});
}
}
}
}