Fix client scheduler shutdown - #122
Conversation
|
I looked a bit further into this because the initial fix felt dirty, and it seems like a regression introduced when the previous The old timer ran on a daemon thread, while the default thread factory used by MC v. 26.2 changed its shutdown behavior, which appears to have made this visible. I've adjusted the fix to restore the previous daemon-thread behavior while still explicitly shutting down the scheduler as part of the client shutdown lifecycle. There are other temporary executors/threads in the tile download path, could be worth auditing separately, but unrelated to this persistent scheduler leak. |
|
Thanks for all your work! I will review and merge it latest next week because I do want to release an update this month. Then I will include this :) |
|
I have now reviewed and tested your changes and came to the conclusion that: private static final Object schedulerLock = new Object();
private static final AtomicInteger schedulerThreadId = new AtomicInteger();
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2, runnable -> {
Thread thread = new Thread(runnable, "MapLink-Scheduler-" + schedulerThreadId.getAndIncrement());
thread.setDaemon(true);
return thread;
});(with getAndIncrement to start at 0) synchronized (schedulerLock) {
if (ms == timerDelay || scheduledSlowUpdateTask == null) return;
timerDelay = ms;
scheduledSlowUpdateTask.cancel(true);
scheduledSlowUpdateTask = scheduler.scheduleAtFixedRate(slowUpdateTask::run, 0, timerDelay, TimeUnit.MILLISECONDS);
}(without the scheduler.isShutdown) Do you want to change your fix to only have these changes or should i commit it and add you as co-author? :) |
Sure, makes sense ^^ changed to getAndIncrement() and removed the scheduler.isShutdown() check + the extra shutdown method. Thanks for testing it and for the feedback! |
b67cd97 to
ebdbae9
Compare
|
Thank you 😄 |
Summary
This fixes a client shutdown issue where Map Link's scheduled update executor can keep the JVM alive after Minecraft has already finished shutting down.
Since the executor uses non-daemon worker threads and was never explicitly stopped, Minecraft can eventually trigger the client shutdown watchdog.
Fix
shutdownNow()[edit]
Reproduction
Originally reproduced with:
Minecraft itself reaches the normal shutdown point:
but the process stays alive until the shutdown watchdog kicks in:
The thread dump still shows the two
ScheduledThreadPoolExecutorworkers used by Map Link.Testing
buildAllscript successfully