small fixes
This commit is contained in:
@@ -8,10 +8,10 @@ namespace MareSynchronos.FileCache;
|
|||||||
|
|
||||||
public class FileCache
|
public class FileCache
|
||||||
{
|
{
|
||||||
public string ResolvedFilepath { get; private set; }
|
public string ResolvedFilepath { get; private set; } = string.Empty;
|
||||||
public string Hash { get; set; }
|
public string Hash { get; set; }
|
||||||
public string PrefixedFilePath { get; init; }
|
public string PrefixedFilePath { get; init; }
|
||||||
public string LastModifiedDateTicks { get; init; }
|
public string LastModifiedDateTicks { get; set; }
|
||||||
|
|
||||||
public FileCache(string hash, string path, string lastModifiedDateTicks)
|
public FileCache(string hash, string path, string lastModifiedDateTicks)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class FileCacheManager : IDisposable
|
|||||||
var hash = splittedEntry[0];
|
var hash = splittedEntry[0];
|
||||||
var path = splittedEntry[1];
|
var path = splittedEntry[1];
|
||||||
var time = splittedEntry[2];
|
var time = splittedEntry[2];
|
||||||
FileCaches[hash] = new FileCache(hash, path, time);
|
FileCaches[path] = new FileCache(hash, path, time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ public class FileCacheManager : IDisposable
|
|||||||
public void WriteOutFullCsv()
|
public void WriteOutFullCsv()
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
foreach (var entry in FileCaches)
|
foreach (var entry in FileCaches.OrderBy(f => f.Value.PrefixedFilePath))
|
||||||
{
|
{
|
||||||
sb.AppendLine(entry.Value.CsvEntry);
|
sb.AppendLine(entry.Value.CsvEntry);
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,15 @@ public class FileCacheManager : IDisposable
|
|||||||
}
|
}
|
||||||
lock (_fileWriteLock)
|
lock (_fileWriteLock)
|
||||||
{
|
{
|
||||||
File.WriteAllText(CsvPath, sb.ToString());
|
try
|
||||||
|
{
|
||||||
|
File.WriteAllText(CsvPath, sb.ToString());
|
||||||
|
File.Delete(CsvBakPath);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
File.WriteAllText(CsvBakPath, sb.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,9 +84,9 @@ public class FileCacheManager : IDisposable
|
|||||||
|
|
||||||
public FileCache? GetFileCacheByHash(string hash)
|
public FileCache? GetFileCacheByHash(string hash)
|
||||||
{
|
{
|
||||||
if (FileCaches.ContainsKey(hash))
|
if (FileCaches.Any(f => f.Value.Hash == hash))
|
||||||
{
|
{
|
||||||
return GetValidatedFileCache(FileCaches[hash]);
|
return GetValidatedFileCache(FileCaches.FirstOrDefault(f => f.Value.Hash == hash).Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -124,7 +132,7 @@ public class FileCacheManager : IDisposable
|
|||||||
var fullName = fi.FullName.ToLowerInvariant();
|
var fullName = fi.FullName.ToLowerInvariant();
|
||||||
if (!fullName.Contains(_configuration.CacheFolder.ToLowerInvariant())) return null;
|
if (!fullName.Contains(_configuration.CacheFolder.ToLowerInvariant())) return null;
|
||||||
string prefixedPath = fullName.Replace(_configuration.CacheFolder.ToLowerInvariant(), CachePrefix + "\\").Replace("\\\\", "\\");
|
string prefixedPath = fullName.Replace(_configuration.CacheFolder.ToLowerInvariant(), CachePrefix + "\\").Replace("\\\\", "\\");
|
||||||
return CreateFileCacheEntity(fi, prefixedPath);
|
return CreateFileCacheEntity(fi, prefixedPath, fi.Name.ToUpper());
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileCache? CreateFileEntry(string path)
|
public FileCache? CreateFileEntry(string path)
|
||||||
@@ -138,16 +146,20 @@ public class FileCacheManager : IDisposable
|
|||||||
return CreateFileCacheEntity(fi, prefixedPath);
|
return CreateFileCacheEntity(fi, prefixedPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FileCache? CreateFileCacheEntity(FileInfo fileInfo, string prefixedPath)
|
private FileCache? CreateFileCacheEntity(FileInfo fileInfo, string prefixedPath, string? hash = null)
|
||||||
{
|
{
|
||||||
var hash = Crypto.GetFileHash(fileInfo.FullName);
|
if (hash == null)
|
||||||
|
{
|
||||||
|
hash = Crypto.GetFileHash(fileInfo.FullName);
|
||||||
|
}
|
||||||
var entity = new FileCache(hash, prefixedPath, fileInfo.LastWriteTimeUtc.Ticks.ToString(CultureInfo.InvariantCulture));
|
var entity = new FileCache(hash, prefixedPath, fileInfo.LastWriteTimeUtc.Ticks.ToString(CultureInfo.InvariantCulture));
|
||||||
FileCaches[hash] = entity;
|
entity = ReplacePathPrefixes(entity);
|
||||||
|
FileCaches[prefixedPath] = entity;
|
||||||
lock (_fileWriteLock)
|
lock (_fileWriteLock)
|
||||||
{
|
{
|
||||||
File.AppendAllLines(CsvPath, new[] { entity.CsvEntry });
|
File.AppendAllLines(CsvPath, new[] { entity.CsvEntry });
|
||||||
}
|
}
|
||||||
var result = GetFileCacheByPath(prefixedPath);
|
var result = GetFileCacheByPath(fileInfo.FullName);
|
||||||
Logger.Debug("Creating file cache for " + fileInfo.FullName + " success: " + (result != null));
|
Logger.Debug("Creating file cache for " + fileInfo.FullName + " success: " + (result != null));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -164,7 +176,7 @@ public class FileCacheManager : IDisposable
|
|||||||
var file = new FileInfo(fileCache.ResolvedFilepath);
|
var file = new FileInfo(fileCache.ResolvedFilepath);
|
||||||
if (!file.Exists)
|
if (!file.Exists)
|
||||||
{
|
{
|
||||||
FileCaches.Remove(fileCache.Hash, out _);
|
FileCaches.Remove(fileCache.PrefixedFilePath, out _);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,10 +195,11 @@ public class FileCacheManager : IDisposable
|
|||||||
|
|
||||||
public void UpdateHash(FileCache fileCache)
|
public void UpdateHash(FileCache fileCache)
|
||||||
{
|
{
|
||||||
var prevHash = fileCache.Hash;
|
Logger.Debug("Updating hash for " + fileCache.ResolvedFilepath);
|
||||||
fileCache.Hash = Crypto.GetFileHash(fileCache.ResolvedFilepath);
|
fileCache.Hash = Crypto.GetFileHash(fileCache.ResolvedFilepath);
|
||||||
FileCaches.Remove(prevHash, out _);
|
fileCache.LastModifiedDateTicks = new FileInfo(fileCache.ResolvedFilepath).LastWriteTimeUtc.Ticks.ToString(CultureInfo.InvariantCulture);
|
||||||
FileCaches[fileCache.Hash] = fileCache;
|
FileCaches.Remove(fileCache.PrefixedFilePath, out _);
|
||||||
|
FileCaches[fileCache.PrefixedFilePath] = fileCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
private FileCache ReplacePathPrefixes(FileCache fileCache)
|
private FileCache ReplacePathPrefixes(FileCache fileCache)
|
||||||
|
|||||||
@@ -201,27 +201,27 @@ public class PeriodicFileScanner : IDisposable
|
|||||||
ConcurrentBag<FileCache> entitiesToUpdate = new();
|
ConcurrentBag<FileCache> entitiesToUpdate = new();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
foreach (var value in _fileDbManager.GetAllFileCaches())
|
foreach (var cache in _fileDbManager.GetAllFileCaches())
|
||||||
{
|
{
|
||||||
var idx = Task.WaitAny(dbTasks, ct);
|
var idx = Task.WaitAny(dbTasks, ct);
|
||||||
dbTasks[idx] = Task.Run(() =>
|
dbTasks[idx] = Task.Run(() =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = _fileDbManager.ValidateFileCacheEntity(value);
|
var validatedCacheResult = _fileDbManager.ValidateFileCacheEntity(cache);
|
||||||
scannedFiles[result.Item2.ResolvedFilepath] = true;
|
scannedFiles[validatedCacheResult.Item2.ResolvedFilepath] = true;
|
||||||
if (result.Item1 == FileState.RequireUpdate)
|
if (validatedCacheResult.Item1 == FileState.RequireUpdate)
|
||||||
{
|
{
|
||||||
entitiesToUpdate.Add(result.Item2);
|
entitiesToUpdate.Add(validatedCacheResult.Item2);
|
||||||
}
|
}
|
||||||
else if (result.Item1 == FileState.RequireDeletion)
|
else if (validatedCacheResult.Item1 == FileState.RequireDeletion)
|
||||||
{
|
{
|
||||||
entitiesToRemove.Add(result.Item2);
|
entitiesToRemove.Add(validatedCacheResult.Item2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Warn("Failed validating " + value.ResolvedFilepath);
|
Logger.Warn("Failed validating " + cache.ResolvedFilepath);
|
||||||
Logger.Warn(ex.Message);
|
Logger.Warn(ex.Message);
|
||||||
Logger.Warn(ex.StackTrace);
|
Logger.Warn(ex.StackTrace);
|
||||||
}
|
}
|
||||||
@@ -278,6 +278,7 @@ public class PeriodicFileScanner : IDisposable
|
|||||||
{
|
{
|
||||||
Logger.Warn("Failed adding " + c.Key);
|
Logger.Warn("Failed adding " + c.Key);
|
||||||
Logger.Warn(ex.Message);
|
Logger.Warn(ex.Message);
|
||||||
|
Logger.Warn(ex.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
Interlocked.Increment(ref currentFileProgress);
|
Interlocked.Increment(ref currentFileProgress);
|
||||||
|
|||||||
@@ -157,8 +157,11 @@ public class CachedPlayer
|
|||||||
while ((toDownloadReplacements = TryCalculateModdedDictionary(out moddedPaths)).Count > 0 && attempts++ <= 10)
|
while ((toDownloadReplacements = TryCalculateModdedDictionary(out moddedPaths)).Count > 0 && attempts++ <= 10)
|
||||||
{
|
{
|
||||||
Logger.Debug("Downloading missing files for player " + PlayerName + ", kind: " + objectKind);
|
Logger.Debug("Downloading missing files for player " + PlayerName + ", kind: " + objectKind);
|
||||||
await _apiController.DownloadFiles(downloadId, toDownloadReplacements, downloadToken);
|
if (toDownloadReplacements.Any())
|
||||||
_apiController.CancelDownload(downloadId);
|
{
|
||||||
|
await _apiController.DownloadFiles(downloadId, toDownloadReplacements, downloadToken);
|
||||||
|
_apiController.CancelDownload(downloadId);
|
||||||
|
}
|
||||||
if (downloadToken.IsCancellationRequested)
|
if (downloadToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
Logger.Verbose("Detected cancellation");
|
Logger.Verbose("Detected cancellation");
|
||||||
|
|||||||
@@ -74,6 +74,23 @@ namespace MareSynchronos.WebAPI
|
|||||||
public int GetDownloadId() => _downloadId++;
|
public int GetDownloadId() => _downloadId++;
|
||||||
|
|
||||||
public async Task DownloadFiles(int currentDownloadId, List<FileReplacementDto> fileReplacementDto, CancellationToken ct)
|
public async Task DownloadFiles(int currentDownloadId, List<FileReplacementDto> fileReplacementDto, CancellationToken ct)
|
||||||
|
{
|
||||||
|
DownloadStarted?.Invoke();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await DownloadFilesInternal(currentDownloadId, fileReplacementDto, ct);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
CancelDownload(currentDownloadId);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DownloadFinished?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DownloadFilesInternal(int currentDownloadId, List<FileReplacementDto> fileReplacementDto, CancellationToken ct)
|
||||||
{
|
{
|
||||||
DownloadStarted?.Invoke();
|
DownloadStarted?.Invoke();
|
||||||
Logger.Debug("Downloading files (Download ID " + currentDownloadId + ")");
|
Logger.Debug("Downloading files (Download ID " + currentDownloadId + ")");
|
||||||
|
|||||||
Reference in New Issue
Block a user