Globalregion stopped ticking sometimes
Stack trace
paste your stack trace or a paste.gg link here!
No stack trace was thrown even the watchdog
Plugin and Datapack List
Actions to reproduce (if known)
No response
Folia version
Commit bb12eee2bdc68452dd643dd6e4efe8ecf68df3ce
Other
It seems that the tick threads are not blocked and the tick task of globalregion got lost.(I will provide more further information if I have time(There is actually a thread dump but it's on my computer and I cannot access it currently))
A thread dump generated by jcmd: https://pastebin.com/20xkNiGX
I've been encountering the same behavior, and I also may have confirmed that the tasks still run, I am not sure as to why, or if it's exactly this, been trying to confirm, but it seems that the global tasks still run .
There's also a wrong use of variable for isWatched
@Spottedleaf
WATCHED_HANDLE for isWatched isn't used, its using the tick
Ok, I found the issue.
final long scheduleTime = Math.max(tick.getScheduledStart(), System.nanoTime()); This is "fixing" the issue, you can replicate the bug by copying teh entire scheduled class and running something like this:
package io.papermc.paper.threadedregions;
import java.util.*;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BooleanSupplier;
public class Main {
public static class BenchmarkRegion extends ScheduledTaskThreadPool.SchedulableTick {
private long lastPeriod = System.nanoTime();
public long getLastPeriod(){
return new Long(lastPeriod);
}
private final long id;
public BenchmarkRegion(long id) {
this.id = id;
}
@Override
public String toDump() {
return String.valueOf(id);
}
private boolean cleaned = false;
public void markCleaned() {
this.cleaned = true;
}
@Override
public boolean runTick() {
this.cleaned = false;
lastPeriod= System.nanoTime();
this.setScheduledStart(System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(50));
return true;
}
@Override
public boolean hasTasks() {
return false;
}
@Override
public boolean runTasks(BooleanSupplier canContinue) {
return true;
}
}
static ScheduledTaskThreadPool scheduler;
public static void main(String[] args) {
scheduler = new ScheduledTaskThreadPool(new ThreadFactory() {
private final AtomicInteger idGenerator = new AtomicInteger();
@Override
public Thread newThread(final Runnable run) {
final Thread ret = new Thread(run, "Region Scheduler Thread #" + this.idGenerator.getAndIncrement());
return ret;
}
}, TimeUnit.MILLISECONDS.toNanos(3), TimeUnit.MILLISECONDS.toNanos(2));
scheduler.setCoreThreads(256);
List<BenchmarkRegion> regions = new ArrayList<>();
for (int i = 0; i < 1024 * 16; i++) {
BenchmarkRegion region = new BenchmarkRegion(i);
region.setScheduledStart(System.nanoTime() + 50);
scheduler.schedule(region);
regions.add(region);
scheduler.notifyTasks(region);
}
Scanner scanner = new Scanner(System.in);
while (true) {
String line = scanner.nextLine();
if (line.equalsIgnoreCase("tps")) {
System.out.println("TPS");
try {
Optional<BenchmarkRegion> benchmarkRegion = regions.stream().min(Comparator.comparingLong(BenchmarkRegion::getLastPeriod));
benchmarkRegion.ifPresent(region -> System.out.println("region: " + region.id + " " + (System.nanoTime() - region.lastPeriod)/(1_000_000.0) +"ms ago. " + region.cleaned));
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
}
}
The new thing I found is that the globalregion gets scheduled before any worker thread started, Idk if it is causing that issue but in the older scheduler, it doesn't act like this