When a file is locked during hash calculation, if retries fails then do not throw exception out but rather return null hash (#7)
Reviewed-on: #7 Co-authored-by: Huy Nguyen <ecenshu@gmail.com> Co-committed-by: Huy Nguyen <ecenshu@gmail.com>
This commit was merged in pull request #7.
This commit is contained in:
@@ -221,8 +221,23 @@ public sealed class SnapshotService : IDisposable, ISnapshotService, IHostedServ
|
|||||||
_watchers.Remove(fileSystemWatchers);
|
_watchers.Remove(fileSystemWatchers);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnChanged(object? _, FileSystemEventArgs e) => ThrottleSnapshotUpdate(e);
|
private void OnChanged(object? _, FileSystemEventArgs e)
|
||||||
private void OnRenamed(object? _, RenamedEventArgs e) => ThrottleSnapshotUpdate(e);
|
{
|
||||||
|
var fileInfo = new FileInfo(e.FullPath);
|
||||||
|
if (_options.ArchiveExtensions.Contains(fileInfo.Extension) || _options.RomExtensions.Contains(fileInfo.Extension))
|
||||||
|
{
|
||||||
|
ThrottleSnapshotUpdate(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnRenamed(object? _, RenamedEventArgs e)
|
||||||
|
{
|
||||||
|
var fileInfo = new FileInfo(e.FullPath);
|
||||||
|
if (_options.ArchiveExtensions.Contains(fileInfo.Extension) || _options.RomExtensions.Contains(fileInfo.Extension))
|
||||||
|
{
|
||||||
|
ThrottleSnapshotUpdate(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rebuild the snapshot, if rebuild in process, cancel it and restart
|
/// Rebuild the snapshot, if rebuild in process, cancel it and restart
|
||||||
@@ -421,7 +436,7 @@ public sealed class SnapshotService : IDisposable, ISnapshotService, IHostedServ
|
|||||||
return fileInfo.LastWriteTimeUtc;
|
return fileInfo.LastWriteTimeUtc;
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
string hash;
|
string? hash;
|
||||||
var ext = Path.GetExtension(file).ToLowerInvariant();
|
var ext = Path.GetExtension(file).ToLowerInvariant();
|
||||||
|
|
||||||
if (!(_options.ArchiveExtensions.Contains(ext) || _options.RomExtensions.Contains(ext)))
|
if (!(_options.ArchiveExtensions.Contains(ext) || _options.RomExtensions.Contains(ext)))
|
||||||
@@ -474,6 +489,8 @@ public sealed class SnapshotService : IDisposable, ISnapshotService, IHostedServ
|
|||||||
Stopwatch stopwatch = Stopwatch.StartNew();
|
Stopwatch stopwatch = Stopwatch.StartNew();
|
||||||
hash = ComputeFirstStreamHashAsync(file, cancellationToken).Result;
|
hash = ComputeFirstStreamHashAsync(file, cancellationToken).Result;
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
|
if (!string.IsNullOrEmpty(hash))
|
||||||
|
{
|
||||||
_logger.LogDebug("Computed hash for {File} in {Time}ms", file, stopwatch.ElapsedMilliseconds);
|
_logger.LogDebug("Computed hash for {File} in {Time}ms", file, stopwatch.ElapsedMilliseconds);
|
||||||
if (_hashCache.TryGetValue(hash, out var value) && file == _cache[value].Path)
|
if (_hashCache.TryGetValue(hash, out var value) && file == _cache[value].Path)
|
||||||
{
|
{
|
||||||
@@ -481,6 +498,7 @@ public sealed class SnapshotService : IDisposable, ISnapshotService, IHostedServ
|
|||||||
yield return null;
|
yield return null;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IEnumerable<(string, long, NcaMetadataWithHash)>? titlesEnumerable = null;
|
IEnumerable<(string, long, NcaMetadataWithHash)>? titlesEnumerable = null;
|
||||||
try
|
try
|
||||||
@@ -572,7 +590,7 @@ public sealed class SnapshotService : IDisposable, ISnapshotService, IHostedServ
|
|||||||
{
|
{
|
||||||
if (_debouncerCache.TryGetValue(_jsonPath, out _))
|
if (_debouncerCache.TryGetValue(_jsonPath, out _))
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Sliding debounce in progress, skipping snapshot persistence");
|
_logger.LogDebug("Sliding debounce in progress, skipping snapshot persistence");
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -821,7 +839,7 @@ public sealed class SnapshotService : IDisposable, ISnapshotService, IHostedServ
|
|||||||
|
|
||||||
// File: TinfoilVibeServer/Services/SnapshotService.cs (inside SnapshotService class)
|
// File: TinfoilVibeServer/Services/SnapshotService.cs (inside SnapshotService class)
|
||||||
|
|
||||||
private async Task<string> ComputeFirstStreamHashAsync(string filePath, CancellationToken cancellationToken = default)
|
private async Task<string?> ComputeFirstStreamHashAsync(string filePath, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
for (var attempt = 0; attempt < _options.MaxRetryCount; attempt++)
|
for (var attempt = 0; attempt < _options.MaxRetryCount; attempt++)
|
||||||
@@ -873,6 +891,11 @@ public sealed class SnapshotService : IDisposable, ISnapshotService, IHostedServ
|
|||||||
attempt + 1, filePath, delay);
|
attempt + 1, filePath, delay);
|
||||||
await Task.Delay(delay, cancellationToken);
|
await Task.Delay(delay, cancellationToken);
|
||||||
}
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Attempt to load {Path} failed after {retries}", filePath, attempt + 1);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
|
|||||||
Reference in New Issue
Block a user