Implement multi-subject and incremental backup

This commit is contained in:
iceBear67 committed 2025-09-28 10:48:45 +08:00
1 parent 82ae81c7af
commit 641fe1ac0a
13 files changed
+249 -117

No files matched your search

+16 -24
View File
@@ -1,8 +1,6 @@
package io.ib67.sfcraft;
import io.ib67.sfcraft.bundler.BundleWriter;
import io.ib67.sfcraft.config.JustBackupConfig;
import io.ib67.sfcraft.mixin.LevelStorageAccessor;
import io.ib67.sfcraft.strategy.BackupStrategy;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
@@ -10,20 +8,25 @@ import net.minecraft.server.MinecraftServer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import static io.ib67.sfcraft.JustBackupMod.BACKUP_LOCK;
import static io.ib67.sfcraft.Globals.BACKUP_LOCK;
@Log4j2
public record BackupWorker(
MinecraftServer server,
BackupStrategy strategy,
JustBackupConfig config
Path tmpDir,
BackupSubject subject,
UnaryOperator<BundleWriter.BundleWriterBuilder> config
) implements Supplier<Backup> {
@SneakyThrows
public BackupWorker {
if (Files.notExists(tmpDir)) Files.createDirectories(tmpDir);
}
@Override
@SneakyThrows
public Backup get() {
@@ -37,29 +40,17 @@ public record BackupWorker(
Thread.sleep(2000);
}
// performing backup is now true
var backupName = "Backup_" + DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(LocalDateTime.now());
var backupParentRoot = Path.of(config.temporaryBackupDir());
if (Files.notExists(backupParentRoot)) Files.createDirectories(backupParentRoot);
var backupFile = backupParentRoot.resolve(backupName + ".jbp.zst");
var tmpBundle = tmpDir.resolve("backup_" + subject + "_" + System.currentTimeMillis() + ".swb.zst");
try {
if (i == 0) {
// not saved yet.
server.saveAll(true, true, false);
}
var session = ((LevelStorageAccessor) server).getSession();
var path = session.getDirectory().getRootPath();
log.info("Creating bundle {}", backupName);
//todo diff
Path worldDir = Path.of(path);
var tree = new WorldDir(worldDir);
BundleWriter.createBundle(backupFile, tree.everything(), c -> c.allowGunzip(config.allowGunzip())
.relativeRoot(worldDir)
.compressionLevel(config.compressionLevel()));
var backup = strategy.createBackup(worldDir, backupFile);
Files.deleteIfExists(backupFile);
return backup;
// tmp file path
log.info("Creating bundle {}", tmpBundle);
BundleWriter.createBundle(tmpBundle, subject.changedFiles(), config);
return strategy.createBackup(subject.name(), subject.root(), tmpBundle);
} catch (Exception e) {
Files.deleteIfExists(backupFile);
throw e;
} finally {
// Though we won't access the state within backup progress, there are certain cases
@@ -69,6 +60,7 @@ public record BackupWorker(
log.error("Expect BACKUP state but got {}", BACKUP_LOCK.get());
Thread.sleep(2000);
}
Files.deleteIfExists(tmpBundle);
}
}
}