145 lines
5.0 KiB
C#
Raw Normal View History

using Logging;
using Utils;
2025-02-26 16:17:20 +01:00
namespace AutoClient.Modes.FolderStore
{
2025-04-03 13:10:01 +02:00
public class FolderSaver : IFileSaverEventHandler
2025-02-26 16:17:20 +01:00
{
private const string FolderSaverFilename = "foldersaver.json";
private readonly App app;
2025-04-03 13:10:01 +02:00
private readonly LoadBalancer loadBalancer;
2025-02-26 16:17:20 +01:00
private readonly JsonFile<FolderStatus> statusFile;
private readonly FolderStatus status;
private readonly BalanceChecker balanceChecker;
2025-05-02 08:21:56 +02:00
private readonly SlowModeHandler slowModeHandler;
2025-02-28 16:19:26 +01:00
private int changeCounter = 0;
2025-05-02 08:21:56 +02:00
private int saveFolderJsonCounter = 0;
2025-02-26 16:17:20 +01:00
2025-04-03 13:10:01 +02:00
public FolderSaver(App app, LoadBalancer loadBalancer)
2025-02-26 16:17:20 +01:00
{
this.app = app;
2025-04-03 13:10:01 +02:00
this.loadBalancer = loadBalancer;
balanceChecker = new BalanceChecker(app);
2025-05-02 08:21:56 +02:00
slowModeHandler = new SlowModeHandler(app);
2025-02-26 16:17:20 +01:00
statusFile = new JsonFile<FolderStatus>(app, Path.Combine(app.Config.FolderToStore, FolderSaverFilename));
status = statusFile.Load();
}
2025-04-04 08:31:27 +02:00
public void Run()
2025-02-26 16:17:20 +01:00
{
2025-05-02 08:21:56 +02:00
saveFolderJsonCounter = 0;
2025-02-26 16:17:20 +01:00
var folderFiles = Directory.GetFiles(app.Config.FolderToStore);
if (!folderFiles.Any()) throw new Exception("No files found in " + app.Config.FolderToStore);
balanceChecker.Check();
2025-02-26 16:17:20 +01:00
foreach (var folderFile in folderFiles)
{
2025-04-04 08:31:27 +02:00
if (app.Cts.IsCancellationRequested) return;
2025-04-03 14:18:27 +02:00
loadBalancer.CheckErrors();
2025-02-26 16:17:20 +01:00
if (!folderFile.ToLowerInvariant().EndsWith(FolderSaverFilename))
{
2025-02-28 16:19:26 +01:00
SaveFile(folderFile);
2025-02-26 16:17:20 +01:00
}
2025-05-02 08:21:56 +02:00
slowModeHandler.Check();
CheckAndSaveChanges();
2025-02-26 16:17:20 +01:00
statusFile.Save(status);
Thread.Sleep(100);
2025-02-26 16:17:20 +01:00
}
}
2025-05-02 08:21:56 +02:00
private void CheckAndSaveChanges()
{
if (changeCounter > 1)
{
changeCounter = 0;
saveFolderJsonCounter++;
if (saveFolderJsonCounter > 5)
{
saveFolderJsonCounter = 0;
balanceChecker.Check();
SaveFolderSaverJsonFile();
}
}
}
2025-02-28 16:19:26 +01:00
private void SaveFile(string folderFile)
2025-02-26 16:17:20 +01:00
{
var localFilename = Path.GetFileName(folderFile);
var entry = status.Files.SingleOrDefault(f => f.Filename == localFilename);
if (entry == null)
{
2025-02-26 16:24:11 +01:00
entry = new FileStatus
{
Filename = localFilename
};
2025-02-26 16:17:20 +01:00
status.Files.Add(entry);
}
2025-02-28 16:19:26 +01:00
ProcessFileEntry(folderFile, entry);
2025-02-26 16:17:20 +01:00
}
2025-02-28 16:19:26 +01:00
private void ProcessFileEntry(string folderFile, FileStatus entry)
2025-02-26 16:17:20 +01:00
{
var fileSaver = CreateFileSaver(folderFile, entry);
fileSaver.Process();
}
private void SaveFolderSaverJsonFile()
{
2025-02-28 16:19:26 +01:00
app.Log.Log($"Saving {FolderSaverFilename}...");
2025-02-26 16:17:20 +01:00
var entry = new FileStatus
{
Filename = FolderSaverFilename
};
var folderFile = Path.Combine(app.Config.FolderToStore, FolderSaverFilename);
ApplyPadding(folderFile);
2025-02-26 16:17:20 +01:00
var fileSaver = CreateFileSaver(folderFile, entry);
fileSaver.Process();
2025-02-28 16:19:26 +01:00
if (!string.IsNullOrEmpty(entry.EncodedCid))
{
app.Log.Log($"!!! {FolderSaverFilename} saved to CID '{entry.EncodedCid}' !!!");
}
else
{
app.Log.Error($"Failed to store {FolderSaverFilename} :|");
}
2025-02-26 16:17:20 +01:00
}
private const int MinCodexStorageFilesize = 262144;
private readonly string paddingMessage = $"Codex currently requires a minimum filesize of {MinCodexStorageFilesize} bytes for datasets used in storage contracts. " +
$"Anything smaller, and the erasure-coding algorithms used for data durability won't function. Therefore, we apply this padding field to make sure this " +
$"file is larger than the minimal size. The following is pseudo-random: ";
private void ApplyPadding(string folderFile)
{
var info = new FileInfo(folderFile);
var min = MinCodexStorageFilesize * 2;
if (info.Length < min)
{
2025-02-27 09:22:57 +01:00
var required = Math.Max(1024, min - info.Length);
status.Padding = paddingMessage + RandomUtils.GenerateRandomString(required);
statusFile.Save(status);
}
}
2025-02-26 16:17:20 +01:00
private FileSaver CreateFileSaver(string folderFile, FileStatus entry)
{
var fixedLength = entry.Filename.PadRight(35);
var prefix = $"[{fixedLength}] ";
2025-05-02 08:21:56 +02:00
return new FileSaver(new LogPrefixer(app.Log, prefix), loadBalancer, status.Stats, folderFile, entry, this, slowModeHandler);
2025-04-03 13:10:01 +02:00
}
public void SaveChanges()
{
statusFile.Save(status);
changeCounter++;
}
2025-02-26 16:17:20 +01:00
}
}