Skip to content

Commit

Permalink
virtual thread capacity
Browse files Browse the repository at this point in the history
  • Loading branch information
wode490390 committed Jan 5, 2024
1 parent b9c0b09 commit fedb4e6
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 32 deletions.
1 change: 0 additions & 1 deletion .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ jobs:
matrix:
java:
[
17,
21,
]
steps:
Expand Down
19 changes: 2 additions & 17 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.jupiter.version>5.10.1</junit.jupiter.version>
<log4j2.version>2.22.0</log4j2.version>
Expand Down Expand Up @@ -432,19 +432,4 @@
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>java21</id>

<activation>
<jdk>21</jdk>
</activation>

<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
</profile>
</profiles>
</project>
4 changes: 4 additions & 0 deletions src/main/java/cn/nukkit/scheduler/AsyncTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ public int getTaskId() {
return this.taskId;
}

protected boolean isVirtual() {
return false;
}

public abstract void onRun();

public void onCompletion(Server server) {
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/cn/nukkit/scheduler/FileWriteTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,8 @@ public void onRun() {
}
}

@Override
protected boolean isVirtual() {
return true;
}
}
20 changes: 19 additions & 1 deletion src/main/java/cn/nukkit/scheduler/NukkitRunnable.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ public synchronized Runnable runTaskAsynchronously(Plugin plugin) throws Illegal
return taskHandler.getTask();
}

public synchronized Runnable runTaskAsynchronously(Plugin plugin, boolean virtual) throws IllegalArgumentException, IllegalStateException {
checkState();
this.taskHandler = Server.getInstance().getScheduler().scheduleTask(plugin, this, true, virtual);
return taskHandler.getTask();
}

public synchronized Runnable runTaskLater(Plugin plugin, int delay) throws IllegalArgumentException, IllegalStateException {
checkState();
this.taskHandler = Server.getInstance().getScheduler().scheduleDelayedTask(plugin, this, delay);
Expand All @@ -42,6 +48,12 @@ public synchronized Runnable runTaskLaterAsynchronously(Plugin plugin, int delay
return taskHandler.getTask();
}

public synchronized Runnable runTaskLaterAsynchronously(Plugin plugin, int delay, boolean virtual) throws IllegalArgumentException, IllegalStateException {
checkState();
this.taskHandler = Server.getInstance().getScheduler().scheduleDelayedTask(plugin, this, delay, true, virtual);
return taskHandler.getTask();
}

public synchronized Runnable runTaskTimer(Plugin plugin, int delay, int period) throws IllegalArgumentException, IllegalStateException {
checkState();
this.taskHandler = Server.getInstance().getScheduler().scheduleDelayedRepeatingTask(plugin, this, delay, period);
Expand All @@ -54,6 +66,12 @@ public synchronized Runnable runTaskTimerAsynchronously(Plugin plugin, int delay
return taskHandler.getTask();
}

public synchronized Runnable runTaskTimerAsynchronously(Plugin plugin, int delay, int period, boolean virtual) throws IllegalArgumentException, IllegalStateException {
checkState();
this.taskHandler = Server.getInstance().getScheduler().scheduleDelayedRepeatingTask(plugin, this, delay, period, true, virtual);
return taskHandler.getTask();
}

/**
* Gets the task id for this runnable.
*
Expand All @@ -72,4 +90,4 @@ private void checkState() {
throw new IllegalStateException("Already scheduled as " + taskHandler.getTaskId());
}
}
}
}
66 changes: 54 additions & 12 deletions src/main/java/cn/nukkit/scheduler/ServerScheduler.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package cn.nukkit.scheduler;

import cn.nukkit.Server;
import cn.nukkit.plugin.Plugin;
import cn.nukkit.utils.PluginException;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
Expand Down Expand Up @@ -85,16 +84,20 @@ public TaskHandler scheduleTask(Plugin plugin, Runnable task, boolean asynchrono
return addTask(plugin, task, 0, 0, asynchronous);
}

public TaskHandler scheduleTask(Plugin plugin, Runnable task, boolean asynchronous, boolean virtual) {
return addTask(plugin, task, 0, 0, asynchronous, virtual);
}

/**
* @deprecated Use {@link #scheduleAsyncTask(Plugin, AsyncTask)
*/
@Deprecated
public TaskHandler scheduleAsyncTask(AsyncTask task) {
return addTask(null, task, 0, 0, true);
return addTask(null, task, 0, 0, true, task.isVirtual());
}

public TaskHandler scheduleAsyncTask(Plugin plugin, AsyncTask task) {
return addTask(plugin, task, 0, 0, true);
return addTask(plugin, task, 0, 0, true, task.isVirtual());
}

public TaskHandler scheduleDelayedTask(Task task, int delay) {
Expand All @@ -105,6 +108,10 @@ public TaskHandler scheduleDelayedTask(Task task, int delay, boolean asynchronou
return this.addTask(task, delay, 0, asynchronous);
}

public TaskHandler scheduleDelayedTask(Task task, int delay, boolean asynchronous, boolean virtual) {
return this.addTask(task, delay, 0, asynchronous, virtual);
}

/**
* @deprecated Use {@link #scheduleDelayedTask(Plugin, Runnable, int)
*/
Expand All @@ -129,6 +136,10 @@ public TaskHandler scheduleDelayedTask(Plugin plugin, Runnable task, int delay,
return addTask(plugin, task, delay, 0, asynchronous);
}

public TaskHandler scheduleDelayedTask(Plugin plugin, Runnable task, int delay, boolean asynchronous, boolean virtual) {
return addTask(plugin, task, delay, 0, asynchronous, virtual);
}

/**
* @deprecated Use {@link #scheduleRepeatingTask(Plugin, Runnable, int)
*/
Expand All @@ -153,6 +164,10 @@ public TaskHandler scheduleRepeatingTask(Plugin plugin, Runnable task, int perio
return addTask(plugin, task, 0, period, asynchronous);
}

public TaskHandler scheduleRepeatingTask(Plugin plugin, Runnable task, int period, boolean asynchronous, boolean virtual) {
return addTask(plugin, task, 0, period, asynchronous, virtual);
}

public TaskHandler scheduleRepeatingTask(Task task, int period) {
return addTask(task, 0, period, false);
}
Expand All @@ -161,6 +176,10 @@ public TaskHandler scheduleRepeatingTask(Task task, int period, boolean asynchro
return addTask(task, 0, period, asynchronous);
}

public TaskHandler scheduleRepeatingTask(Task task, int period, boolean asynchronous, boolean virtual) {
return addTask(task, 0, period, asynchronous, virtual);
}

public TaskHandler scheduleDelayedRepeatingTask(Task task, int delay, int period) {
return addTask(task, delay, period, false);
}
Expand All @@ -169,6 +188,10 @@ public TaskHandler scheduleDelayedRepeatingTask(Task task, int delay, int period
return addTask(task, delay, period, asynchronous);
}

public TaskHandler scheduleDelayedRepeatingTask(Task task, int delay, int period, boolean asynchronous, boolean virtual) {
return addTask(task, delay, period, asynchronous, virtual);
}

/**
* @deprecated Use {@link #scheduleDelayedRepeatingTask(Plugin, Runnable, int, int)
*/
Expand All @@ -193,6 +216,10 @@ public TaskHandler scheduleDelayedRepeatingTask(Plugin plugin, Runnable task, in
return addTask(plugin, task, delay, period, asynchronous);
}

public TaskHandler scheduleDelayedRepeatingTask(Plugin plugin, Runnable task, int delay, int period, boolean asynchronous, boolean virtual) {
return addTask(plugin, task, delay, period, asynchronous, virtual);
}

public void cancelTask(int taskId) {
TaskHandler taskHandler = taskMap.remove(taskId);
if (taskHandler != null) {
Expand Down Expand Up @@ -240,18 +267,26 @@ public boolean isQueued(int taskId) {
}

private TaskHandler addTask(Task task, int delay, int period, boolean asynchronous) {
return addTask(task instanceof PluginTask ? ((PluginTask) task).getOwner() : null, task, delay, period, asynchronous);
return addTask(task instanceof PluginTask ? ((PluginTask) task).getOwner() : null, task, delay, period, asynchronous, false);
}

private TaskHandler addTask(Task task, int delay, int period, boolean asynchronous, boolean virtual) {
return addTask(task instanceof PluginTask ? ((PluginTask) task).getOwner() : null, task, delay, period, asynchronous, virtual);
}

private TaskHandler addTask(Plugin plugin, Runnable task, int delay, int period, boolean asynchronous) {
return addTask(plugin, task, delay, period, asynchronous, false);
}

private TaskHandler addTask(Plugin plugin, Runnable task, int delay, int period, boolean asynchronous, boolean virtual) {
if (plugin != null && plugin.isDisabled()) {
throw new PluginException("Plugin '" + plugin.getName() + "' attempted to register a task while disabled.");
}
if (delay < 0 || period < 0) {
throw new PluginException("Attempted to register a task with negative delay or period.");
}

TaskHandler taskHandler = new TaskHandler(plugin, task, nextTaskId(), asynchronous);
TaskHandler taskHandler = new TaskHandler(plugin, task, nextTaskId(), asynchronous, virtual);
taskHandler.setDelay(delay);
taskHandler.setPeriod(period);
taskHandler.setNextRunTick(taskHandler.isDelayed() ? currentTick + taskHandler.getDelay() : currentTick);
Expand Down Expand Up @@ -280,13 +315,20 @@ public void mainThreadHeartbeat(int currentTick) {
taskMap.remove(taskHandler.getTaskId());
continue;
} else if (taskHandler.isAsynchronous()) {
asyncPool.execute(() -> {
try {
taskHandler.getTask().run();
} catch (Throwable e) {
log.fatal("Exception in asynchronous task", e);
}
});
if (taskHandler.isVirtual()) {
Thread.ofVirtual()
.name("Nukkit Asynchronous (Virtual) Task Handler #", 0)
.uncaughtExceptionHandler((thread, ex) -> log.fatal("Exception in asynchronous (virtual) task", ex))
.start(taskHandler.getTask());
} else {
asyncPool.execute(() -> {
try {
taskHandler.getTask().run();
} catch (Throwable e) {
log.fatal("Exception in asynchronous task", e);
}
});
}
} else {
try {
taskHandler.run(currentTick);
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/cn/nukkit/scheduler/TaskHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
public class TaskHandler {
private final int taskId;
private final boolean asynchronous;
private final boolean virtual;

private final Plugin plugin;
private final Runnable task;
Expand All @@ -22,11 +23,12 @@ public class TaskHandler {

private boolean cancelled;

public TaskHandler(Plugin plugin, Runnable task, int taskId, boolean asynchronous) {
public TaskHandler(Plugin plugin, Runnable task, int taskId, boolean asynchronous, boolean virtual) {
this.asynchronous = asynchronous;
this.plugin = plugin;
this.task = task;
this.taskId = taskId;
this.virtual = virtual;
}

public boolean isCancelled() {
Expand Down Expand Up @@ -107,6 +109,10 @@ public boolean isAsynchronous() {
return asynchronous;
}

public boolean isVirtual() {
return virtual;
}

public void setDelay(int delay) {
this.delay = delay;
}
Expand Down

0 comments on commit fedb4e6

Please sign in to comment.