Commented some more code.
BackupScheduler is now static
This commit is contained in:
parent
6707e813b2
commit
81c5cd04cb
@ -36,16 +36,13 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class Globals {
|
||||
public static final Globals INSTANCE = new Globals();
|
||||
public final static DateTimeFormatter defaultDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss");
|
||||
|
||||
private final static TextileLogger log = new TextileLogger(TextileBackup.MOD_NAME);
|
||||
public final static DateTimeFormatter defaultDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss");
|
||||
|
||||
private ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||
public final AtomicBoolean globalShutdownBackupFlag = new AtomicBoolean(true);
|
||||
|
||||
public boolean disableWatchdog = false;
|
||||
private boolean disableTMPFiles = false;
|
||||
|
||||
private AwaitThread restoreAwaitThread = null;
|
||||
private Path lockedPath = null;
|
||||
|
||||
|
@ -55,7 +55,7 @@ public class TextileBackup implements ModInitializer {
|
||||
|
||||
ConfigHelper.updateInstance(AutoConfig.register(ConfigPOJO.class, JanksonConfigSerializer::new));
|
||||
|
||||
ServerTickEvents.END_SERVER_TICK.register(new BackupScheduler()::tick);
|
||||
ServerTickEvents.END_SERVER_TICK.register(BackupScheduler::tick);
|
||||
|
||||
//Restart Executor Service in single-player
|
||||
ServerLifecycleEvents.SERVER_STARTING.register(server -> {
|
||||
@ -63,6 +63,7 @@ public class TextileBackup implements ModInitializer {
|
||||
Globals.INSTANCE.updateTMPFSFlag(server);
|
||||
});
|
||||
|
||||
//Wait 60s for already submited backups to finish. After that kill the bastards and run the one last if required
|
||||
ServerLifecycleEvents.SERVER_STOPPED.register(server -> {
|
||||
Globals.INSTANCE.shutdownQueueExecutor(60000);
|
||||
|
||||
|
@ -18,10 +18,13 @@
|
||||
|
||||
package net.szum123321.textile_backup.core;
|
||||
|
||||
/**
|
||||
* Enum representing possible sources of action
|
||||
*/
|
||||
public enum ActionInitiator {
|
||||
Player("Player", "by"),
|
||||
ServerConsole("Server Console", "from"),
|
||||
Timer("Timer", "by"),
|
||||
ServerConsole("Server Console", "from"), //some/ting typed a command and it was not a player (command blocks and server console count)
|
||||
Timer("Timer", "by"), //a.k.a scheduler
|
||||
Shutdown("Server Shutdown", "by"),
|
||||
Restore("Backup Restoration", "because of"),
|
||||
Null("Null (That shouldn't have happened)", "form");
|
||||
|
@ -33,6 +33,9 @@ import java.time.ZoneOffset;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Set of utility used for removing old backups
|
||||
*/
|
||||
public class Cleanup {
|
||||
private final static TextileLogger log = new TextileLogger(TextileBackup.MOD_NAME);
|
||||
private final static ConfigHelper config = ConfigHelper.INSTANCE;
|
||||
@ -55,7 +58,7 @@ public class Cleanup {
|
||||
}
|
||||
|
||||
final int noToKeep = config.get().backupsToKeep > 0 ? config.get().backupsToKeep : Integer.MAX_VALUE;
|
||||
final long maxSize = config.get().maxSize > 0 ? config.get().maxSize * 1024: Long.MAX_VALUE;
|
||||
final long maxSize = config.get().maxSize > 0 ? config.get().maxSize * 1024: Long.MAX_VALUE; //max number of bytes to keep
|
||||
|
||||
long[] counts = count(root);
|
||||
long n = counts[0], size = counts[1];
|
||||
|
@ -40,6 +40,9 @@ import java.util.stream.Stream;
|
||||
|
||||
import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
|
||||
|
||||
/**
|
||||
* This class parses backup files, extracting its creation time, format and possibly comment
|
||||
*/
|
||||
public class RestoreableFile implements Comparable<RestoreableFile> {
|
||||
private final Path file;
|
||||
private final ConfigPOJO.ArchiveFormat archiveFormat;
|
||||
@ -53,6 +56,7 @@ public class RestoreableFile implements Comparable<RestoreableFile> {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
//removes repetition of the files stream thingy with awfully large lambdas
|
||||
public static <T> T applyOnFiles(Path root, T def, Consumer<IOException> errorConsumer, Function<Stream<RestoreableFile>, T> streamConsumer) {
|
||||
try (Stream<Path> stream = Files.list(root)) {
|
||||
return streamConsumer.apply(stream.flatMap(f -> RestoreableFile.build(f).stream()));
|
||||
|
@ -65,7 +65,6 @@ public class Utilities {
|
||||
.getWorldDirectory(World.OVERWORLD);
|
||||
}
|
||||
|
||||
|
||||
public static void deleteDirectory(Path path) throws IOException {
|
||||
Files.walkFileTree(path, new SimplePathVisitor() {
|
||||
@Override
|
||||
|
@ -21,12 +21,9 @@ package net.szum123321.textile_backup.core.create;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.util.Util;
|
||||
import net.szum123321.textile_backup.core.ActionInitiator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public record BackupContext(@NotNull MinecraftServer server,
|
||||
ServerCommandSource commandSource,
|
||||
ActionInitiator initiator,
|
||||
@ -103,8 +100,7 @@ public record BackupContext(@NotNull MinecraftServer server,
|
||||
|
||||
if (server == null) {
|
||||
if (commandSource != null) setServer(commandSource.getServer());
|
||||
else
|
||||
throw new RuntimeException("Neither MinecraftServer or ServerCommandSource were provided!");
|
||||
else throw new RuntimeException("Neither MinecraftServer or ServerCommandSource were provided!");
|
||||
}
|
||||
|
||||
return new BackupContext(server, commandSource, initiator, save, comment);
|
||||
|
@ -25,24 +25,32 @@ import net.szum123321.textile_backup.core.ActionInitiator;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* Runs backup on a preset interval
|
||||
* <br>
|
||||
* The important thing to note: <br>
|
||||
* In the case that <code>doBackupsOnEmptyServer == false</code> and there have been made backups with players online,
|
||||
* then everyone left the backup that was scheduled with player is still going to run. So it might appear as though there
|
||||
* has been made backup with no players online despite the config. This is the expected behaviour
|
||||
* <br>
|
||||
* Furthermore, it uses system time
|
||||
*/
|
||||
public class BackupScheduler {
|
||||
private final static ConfigHelper config = ConfigHelper.INSTANCE;
|
||||
|
||||
private boolean scheduled;
|
||||
private long nextBackup;
|
||||
//Scheduled flag tells whether we have decided to run another backup
|
||||
private static boolean scheduled = false;
|
||||
private static long nextBackup = - 1;
|
||||
|
||||
public BackupScheduler() {
|
||||
scheduled = false;
|
||||
nextBackup = -1;
|
||||
}
|
||||
|
||||
public void tick(MinecraftServer server) {
|
||||
public static void tick(MinecraftServer server) {
|
||||
if(config.get().backupInterval < 1) return;
|
||||
long now = Instant.now().getEpochSecond();
|
||||
|
||||
if(config.get().doBackupsOnEmptyServer || server.getPlayerManager().getCurrentPlayerCount() > 0) {
|
||||
//Either just run backup with no one playing or there's at least one player
|
||||
if(scheduled) {
|
||||
if(nextBackup <= now) {
|
||||
//It's time to run
|
||||
Globals.INSTANCE.getQueueExecutor().submit(
|
||||
MakeBackupRunnableFactory.create(
|
||||
BackupContext.Builder
|
||||
@ -57,11 +65,15 @@ public class BackupScheduler {
|
||||
nextBackup = now + config.get().backupInterval;
|
||||
}
|
||||
} else {
|
||||
//Either server just started or a new player joined after the last backup has finished
|
||||
//So let's schedule one some time from now
|
||||
nextBackup = now + config.get().backupInterval;
|
||||
scheduled = true;
|
||||
}
|
||||
} else if(!config.get().doBackupsOnEmptyServer && server.getPlayerManager().getCurrentPlayerCount() == 0) {
|
||||
//Do the final backup. No one's on-line and doBackupsOnEmptyServer == false
|
||||
if(scheduled && nextBackup <= now) {
|
||||
//Verify we hadn't done the final one and its time to do so
|
||||
Globals.INSTANCE.getQueueExecutor().submit(
|
||||
MakeBackupRunnableFactory.create(
|
||||
BackupContext.Builder
|
||||
|
@ -37,6 +37,9 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* The actual object responsible for creating the backup
|
||||
*/
|
||||
public class MakeBackupRunnable implements Runnable {
|
||||
private final static TextileLogger log = new TextileLogger(TextileBackup.MOD_NAME);
|
||||
private final static ConfigHelper config = ConfigHelper.INSTANCE;
|
||||
@ -87,7 +90,7 @@ public class MakeBackupRunnable implements Runnable {
|
||||
log.trace("Using PARALLEL Zip Compressor. Threads: {}", coreCount);
|
||||
} else {
|
||||
ZipCompressor.getInstance().createArchive(world, outFile, context, coreCount);
|
||||
log.trace("Using REGULAR Zip Compressor. Threads: {}");
|
||||
log.trace("Using REGULAR Zip Compressor.");
|
||||
}
|
||||
}
|
||||
case BZIP2 -> ParallelBZip2Compressor.getInstance().createArchive(world, outFile, context, coreCount);
|
||||
|
@ -33,6 +33,9 @@ import java.time.Instant;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Basic abstract class representing directory compressor
|
||||
*/
|
||||
public abstract class AbstractCompressor {
|
||||
private final static TextileLogger log = new TextileLogger(TextileBackup.MOD_NAME);
|
||||
|
||||
@ -88,7 +91,7 @@ public abstract class AbstractCompressor {
|
||||
protected abstract void addEntry(Path file, String entryName, OutputStream arc) throws IOException;
|
||||
|
||||
protected void finish(OutputStream arc) throws InterruptedException, ExecutionException, IOException {
|
||||
//Basically this function is only needed for the ParallelZipCompressor to write out ParallelScatterZipCreator
|
||||
//This function is only needed for the ParallelZipCompressor to write out ParallelScatterZipCreator
|
||||
}
|
||||
|
||||
protected void close() {
|
||||
|
@ -35,6 +35,7 @@ import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
//TODO: Verify backup's validity?
|
||||
public class RestoreBackupRunnable implements Runnable {
|
||||
private final static TextileLogger log = new TextileLogger(TextileBackup.MOD_NAME);
|
||||
private final static ConfigHelper config = ConfigHelper.INSTANCE;
|
||||
|
@ -25,6 +25,10 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
|
||||
/**
|
||||
* This mixin should numb Watchdog while a backup runs.
|
||||
* If works as intended solves issues with watchdog errors
|
||||
*/
|
||||
@Mixin(DedicatedServerWatchdog.class)
|
||||
public class DedicatedServerWatchdogMixin {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user