Skip to content

Commit

Permalink
Fix fabric server hanging on shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
Axionize committed Oct 15, 2024
1 parent 8085145 commit 538b2bf
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 20 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
id("fabric-loom") version "1.7.4" apply false
}

val fullVersion = "1.3.2"
val fullVersion = "1.3.4"
val snapshot = true

allprojects {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public final class KnockbackSyncPlugin extends JavaPlugin {
{
statsManager = new BukkitStatsManager();
platformServer = new BukkitServer();
pluginJarHashProvider = new PluginJarHashProvider(Bukkit.getPluginManager().getPlugin("KnockbackSync").getClass().getProtectionDomain().getCodeSource().getLocation());
pluginJarHashProvider = new PluginJarHashProvider(this.getClass().getProtectionDomain().getCodeSource().getLocation());
}

private final PluginPermissionChecker permissionChecker = new PluginPermissionChecker();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,10 @@ public AbstractTaskHandle runTaskLaterAsynchronously(Runnable task, long delay)
public AbstractTaskHandle runTaskTimerAsynchronously(Runnable task, long delay, long period) {
return new BukkitTaskHandle(scheduler.runTaskTimerAsynchronously(plugin, task, delay, period));
}

// Bukkit should take care of this for us automatically
@Override
public void shutdown() {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,10 @@ public AbstractTaskHandle runTaskLaterAsynchronously(Runnable task, long delay)
public AbstractTaskHandle runTaskTimerAsynchronously(Runnable task, long delay, long period) {
return new FoliaTaskHandle(scheduler.runAtFixedRate(plugin, scheduledTask -> task.run(), delay, period));
}

// Folia takes care of this
@Override
public void shutdown() {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import me.caseload.knockbacksync.KnockbackSyncBase;

public class BukkitStatsManager extends StatsManager {

@Override
public void init() {
KnockbackSyncBase.INSTANCE.getScheduler().runTaskAsynchronously(() -> {
BuildTypePie.determineBuildType(); // Function to calculate hash
MetricsBukkit metrics = new MetricsBukkit(23568);
metrics.addCustomChart(new PlayerVersionsPie());
metrics.addCustomChart(new BuildTypePie());
super.metrics = metrics;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ public MetricsBukkit(int serviceId) {
/**
* Shuts down the underlying scheduler service.
*/
@Override
public void shutdown() {
metricsBase.shutdown();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ public interface SchedulerAdapter {
AbstractTaskHandle runTaskTimer(Runnable task, long delayTicks, long periodTicks);
AbstractTaskHandle runTaskLaterAsynchronously(Runnable task, long delay);
AbstractTaskHandle runTaskTimerAsynchronously(Runnable task, long delay, long period);
void shutdown();
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package me.caseload.knockbacksync.stats.custom;

public interface Metrics {
public void shutdown();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

public abstract class StatsManager {

Metrics metrics;

public Metrics getMetrics() {
return metrics;
}

public void init() {
throw new IllegalStateException("Empty stats class!");
}
Expand Down
3 changes: 1 addition & 2 deletions fabric/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ dependencies {
modImplementation("net.fabricmc.fabric-api:fabric-api:${rootProject.property("fabric_version")}")

include(modImplementation("me.lucko:fabric-permissions-api:0.3.1")!!)
include(modImplementation("com.github.retrooper:packetevents-fabric:2.5.7-SNAPSHOT")!!)
include(modImplementation("com.github.retrooper:packetevents-fabric:2.5.8-SNAPSHOT")!!)

shadeThisThing(implementation("com.fasterxml.jackson.core:jackson-databind:2.17.2")!!)
shadeThisThing(implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.17.2")!!)
Expand Down Expand Up @@ -61,7 +61,6 @@ tasks.remapJar {
inputFile = tasks.shadowJar.get().archiveFile
}


tasks.processResources {
inputs.property("version", project.version)
inputs.property("minecraft_version", rootProject.property("minecraft_version"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ public void onInitialize() {
core.configManager.loadConfig(false);
core.statsManager.init();
core.checkForUpdates();
ServerLifecycleEvents.SERVER_STOPPING.register((server) -> {
core.scheduler.shutdown();
core.statsManager.getMetrics().shutdown();
});
}

public static MinecraftServer getServer() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,19 @@
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.server.MinecraftServer;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.*;

public class FabricSchedulerAdapter implements SchedulerAdapter {
// private final MinecraftServer server;
private final List<ScheduledTask> taskList;
private final Map<ScheduledTask, Runnable> taskMap = new HashMap<>();
private final Map<Thread, Runnable> asyncTasks = new HashMap<>();

public FabricSchedulerAdapter() {
// this.server = KnockbackSyncFabric.SERVER;
this.taskList = new ArrayList<>();
ServerTickEvents.END_SERVER_TICK.register(this::handleTasks);
}

private void handleTasks(MinecraftServer server) {
Iterator<ScheduledTask> iterator = taskList.iterator();
Iterator<ScheduledTask> iterator = taskMap.keySet().iterator();
while (iterator.hasNext()) {
ScheduledTask task = iterator.next();
if (server.getTickCount() >= task.nextRunTick) {
Expand All @@ -37,29 +34,37 @@ private void handleTasks(MinecraftServer server) {
@Override
public AbstractTaskHandle runTask(Runnable task) {
ScheduledTask scheduledTask = new ScheduledTask(task, KnockbackSyncFabric.getServer().getTickCount(), 0, false);
taskList.add(scheduledTask);
return new FabricTaskHandle(() -> taskList.remove(scheduledTask));
Runnable cancellationTask = () -> taskMap.remove(scheduledTask);
taskMap.put(scheduledTask, cancellationTask);
return new FabricTaskHandle(cancellationTask);
}

@Override
public AbstractTaskHandle runTaskAsynchronously(Runnable task) {
Thread thread = new Thread(task);
Runnable cancellationTask = () -> {
thread.interrupt();
asyncTasks.remove(thread);
};
asyncTasks.put(thread, cancellationTask);
thread.start();
return new FabricTaskHandle(() -> thread.interrupt());
return new FabricTaskHandle(cancellationTask);
}

@Override
public AbstractTaskHandle runTaskLater(Runnable task, long delayTicks) {
ScheduledTask scheduledTask = new ScheduledTask(task, KnockbackSyncFabric.getServer().getTickCount() + delayTicks, 0, false);
taskList.add(scheduledTask);
return new FabricTaskHandle(() -> taskList.remove(scheduledTask));
Runnable cancellationTask = () -> taskMap.remove(scheduledTask);
taskMap.put(scheduledTask, cancellationTask);
return new FabricTaskHandle(cancellationTask);
}

@Override
public AbstractTaskHandle runTaskTimer(Runnable task, long delayTicks, long periodTicks) {
ScheduledTask scheduledTask = new ScheduledTask(task, KnockbackSyncFabric.getServer().getTickCount() + delayTicks, periodTicks, true);
taskList.add(scheduledTask);
return new FabricTaskHandle(() -> taskList.remove(scheduledTask));
Runnable cancellationTask = () -> taskMap.remove(scheduledTask);
taskMap.put(scheduledTask, cancellationTask);
return new FabricTaskHandle(cancellationTask);
}

@Override
Expand All @@ -72,8 +77,13 @@ public AbstractTaskHandle runTaskLaterAsynchronously(Runnable task, long delay)
// Handle interruption
}
});
Runnable cancellationTask = () -> {
thread.interrupt();
asyncTasks.remove(thread);
};
asyncTasks.put(thread, cancellationTask);
thread.start();
return new FabricTaskHandle(() -> thread.interrupt());
return new FabricTaskHandle(cancellationTask);
}

@Override
Expand All @@ -89,8 +99,34 @@ public AbstractTaskHandle runTaskTimerAsynchronously(Runnable task, long delay,
// Handle interruption
}
});
Runnable cancellationTask = () -> {
thread.interrupt();
asyncTasks.remove(thread);
};
asyncTasks.put(thread, cancellationTask);
thread.start();
return new FabricTaskHandle(() -> thread.interrupt());
return new FabricTaskHandle(cancellationTask);
}

@Override
public void shutdown() {
// Create a new list to store the tasks that need to be executed
List<Runnable> tasksToExecute = new ArrayList<>();

// Add the tasks from the taskMap to the tasksToExecute list
tasksToExecute.addAll(taskMap.values());

// Add the tasks from the asyncTasks to the tasksToExecute list
tasksToExecute.addAll(asyncTasks.values());

// Clear the taskMap and asyncTasks to avoid further modifications
taskMap.clear();
asyncTasks.clear();

// Execute the tasks in the tasksToExecute list
for (Runnable task : tasksToExecute) {
task.run();
}
}

private static class ScheduledTask {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public void init() {
MetricsFabric metrics = new MetricsFabric(23568);
metrics.addCustomChart(new PlayerVersionsPie());
metrics.addCustomChart(new BuildTypePie());
super.metrics = metrics;
});
}
}

0 comments on commit 538b2bf

Please sign in to comment.