Allow server to be stopped cleanly

This commit is contained in:
jglrxavpok 2020-04-28 19:22:54 +02:00
parent 98875df389
commit 9b25f5d95b
6 changed files with 59 additions and 1 deletions

View File

@ -15,6 +15,7 @@ import net.minestom.server.item.Material;
import net.minestom.server.network.packet.server.play.DeclareRecipesPacket;
import net.minestom.server.recipe.RecipeManager;
import net.minestom.server.recipe.ShapelessRecipe;
import net.minestom.server.timer.TaskRunnable;
import net.minestom.server.utils.time.TimeUnit;
import net.minestom.server.utils.time.UpdateOption;
@ -50,6 +51,13 @@ public class Main {
MinecraftServer.getBenchmarkManager().enable(new UpdateOption(10 * 1000, TimeUnit.MILLISECOND));
MinecraftServer.getSchedulerManager().addShutdownTask(new TaskRunnable() {
@Override
public void run() {
System.out.println("Good night");
}
});
PlayerInit.init();
minecraftServer.start("localhost", 55555, PlayerInit.getResponseDataConsumer());

View File

@ -1,5 +1,6 @@
package fr.themode.demo.commands;
import net.minestom.server.MinecraftServer;
import net.minestom.server.command.CommandProcessor;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.Player;
@ -26,6 +27,8 @@ public class SimpleCommand implements CommandProcessor {
creature.setPathTo(player.getPosition());
}
MinecraftServer.stopCleanly();
return true;
}

View File

@ -187,4 +187,13 @@ public class MinecraftServer {
nettyServer.start(address, port);
}
/**
* Stops this server properly (saves if needed, kicking players, etc.)
*/
public static void stopCleanly() {
updateManager.stop();
nettyServer.stop();
schedulerManager.shutdown();
}
}

View File

@ -13,6 +13,7 @@ import java.util.concurrent.ExecutorService;
public class UpdateManager {
private ExecutorService mainUpdate = new MinestomThread(MinecraftServer.THREAD_COUNT_MAIN_UPDATE, MinecraftServer.THREAD_NAME_MAIN_UPDATE);
private boolean stopRequested;
public void start() {
@ -25,7 +26,7 @@ public class UpdateManager {
final long tickDistance = MinecraftServer.TICK_MS * 1000000;
long currentTime;
while (true) {
while (!stopRequested) {
currentTime = System.nanoTime();
// Keep Alive Handling
@ -63,4 +64,7 @@ public class UpdateManager {
});
}
public void stop() {
stopRequested = true;
}
}

View File

@ -1,6 +1,7 @@
package net.minestom.server.network.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
@ -62,4 +63,12 @@ public class NettyServer {
public int getPort() {
return port;
}
public void stop() {
try {
group.shutdownGracefully().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@ -13,8 +13,10 @@ import java.util.concurrent.atomic.AtomicInteger;
public class SchedulerManager {
private static final AtomicInteger COUNTER = new AtomicInteger();
private static final AtomicInteger SHUTDOWN_COUNTER = new AtomicInteger();
private static ExecutorService batchesPool = new MinestomThread(MinecraftServer.THREAD_COUNT_SCHEDULER, MinecraftServer.THREAD_NAME_SCHEDULER);
private List<Task> tasks = new CopyOnWriteArrayList<>();
private List<Task> shutdownTasks = new CopyOnWriteArrayList<>();
public int addTask(TaskRunnable runnable, UpdateOption updateOption, int maxCallCount) {
int id = COUNTER.incrementAndGet();
@ -34,6 +36,29 @@ public class SchedulerManager {
return addTask(runnable, updateOption, 1);
}
/**
* Adds a task to run when the server shutdowns
* @param runnable the task to perform
* @return
*/
public int addShutdownTask(TaskRunnable runnable) {
int id = SHUTDOWN_COUNTER.incrementAndGet();
runnable.setId(id);
Task task = new Task(runnable, null, 1);
this.shutdownTasks.add(task);
return id;
}
public void shutdown() {
batchesPool.execute(() -> {
for (Task task : shutdownTasks) {
task.getRunnable().run();
}
});
}
public void removeTask(int taskId) {
this.tasks.removeIf(task -> task.getId() == taskId);
}