SteamWar/SpigotCore
Archiviert
13
0

First tested checkpoint implementation #253

Zusammengeführt
Lixfel hat 2 Commits von checkpoint nach master 2024-01-16 15:03:47 +01:00 zusammengeführt
Nur Änderungen aus Commit c0b111eabc werden angezeigt - Alle Commits anzeigen

Datei anzeigen

@ -21,6 +21,7 @@ package de.steamwar.core;
import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import com.viaversion.viaversion.api.Via;
import de.steamwar.sql.internal.Statement;
import io.netty.channel.ChannelFuture;
import org.bukkit.Bukkit;
@ -28,22 +29,46 @@ import org.eclipse.openj9.criu.CRIUSupport;
import org.eclipse.openj9.criu.JVMCRIUException;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.List;
import java.util.logging.Level;
import java.util.stream.Stream;
public class CheckpointUtils {
private CheckpointUtils() {}
private static final Reflection.FieldAccessor<List> channelFutures = Reflection.getField(TinyProtocol.serverConnection, List.class, 0, ChannelFuture.class);
private static final Reflection.MethodInvoker bind = Reflection.getMethod(TinyProtocol.serverConnection, null, InetAddress.class, int.class);
public static void freeze() {
Bukkit.getOnlinePlayers().forEach(player -> player.kickPlayer(null));
Path path = FileSystems.getDefault().getPath(System.getProperty("checkpoint"));
try {
freezeInternal(path);
} catch (Exception e) {
Bukkit.shutdown();
throw new SecurityException(e);
} finally {
// Delete checkpoint
try (Stream<Path> stream = Files.walk(path)) {
stream.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
} catch (IOException e) {
//ignore
}
}
}
private static void freezeInternal(Path path) throws Exception {
Statement.closeAll();
// Close socket
Lixfel markierte diese Unterhaltung als gelöst
Review

Datei würde ich nach port lesen auch löschen. Damit das nicht einfach so da bleibt.

Datei würde ich nach port lesen auch löschen. Damit das nicht einfach so da bleibt.
Via.getManager().getInjector().uninject();
Object serverConnection = TinyProtocol.getServerConnection(Core.getInstance());
List<?> channels = channelFutures.get(serverConnection);
for(Object future : channels) {
@ -51,13 +76,13 @@ public class CheckpointUtils {
}
channels.clear();
// Do the snapshot
Path path = FileSystems.getDefault().getPath("/tmp/checkpoints/" + Core.getVersion() + "/" + Bukkit.getWorlds().get(0).getName());
// Do the checkpoint
path.toFile().mkdirs();
CRIUSupport criu = new CRIUSupport(path);
criu.setAutoDedup(true);
//criu.setShellJob(true);
//criu.setWorkDir(path); criu.setLogFile("criu.log");
criu.setFileLocks(true);
criu.setShellJob(true);
criu.setLogFile("criu.log");
try {
criu.checkpointJVM();
} catch (JVMCRIUException e) {
@ -69,9 +94,6 @@ public class CheckpointUtils {
int port;
try (DataInputStream stream = new DataInputStream(Files.newInputStream(path.resolve("port").toFile().toPath()))) {
port = stream.readInt();
} catch (IOException e) {
Bukkit.shutdown();
throw new SecurityException(e);
}
// Reopen socket
@ -81,5 +103,8 @@ public class CheckpointUtils {
((ChannelFuture) future).channel().config().setAutoRead(true);
}
}
Via.getManager().getInjector().inject();
Core.getInstance().getLogger().log(Level.INFO, "Checkpoint restored");
}
}