oops, touch requests are concurrent...

This commit is contained in:
Loporrit
2024-09-09 07:03:08 +00:00
parent 908c34f57b
commit 1f57510bb7
3 changed files with 32 additions and 20 deletions

View File

@@ -114,7 +114,7 @@ public sealed class CachedFileProvider : IDisposable
if (string.IsNullOrEmpty(_coldStoragePath)) return false; if (string.IsNullOrEmpty(_coldStoragePath)) return false;
var coldStorageFilePath = FilePathUtil.GetFilePath(_coldStoragePath, hash); var coldStorageFilePath = FilePathUtil.GetFilePath(_coldStoragePath, hash);
if (coldStorageFilePath == null) return false; if (!File.Exists(coldStorageFilePath)) return false;
try try
{ {

View File

@@ -1,5 +1,6 @@
using MareSynchronosShared.Services; using MareSynchronosShared.Services;
using MareSynchronosStaticFilesServer.Utils; using MareSynchronosStaticFilesServer.Utils;
using System.Collections.Concurrent;
namespace MareSynchronosStaticFilesServer.Services; namespace MareSynchronosStaticFilesServer.Services;
@@ -10,12 +11,13 @@ public class ColdTouchHashService : ITouchHashService
private readonly IConfigurationService<StaticFilesServerConfiguration> _configuration; private readonly IConfigurationService<StaticFilesServerConfiguration> _configuration;
private readonly bool _useColdStorage; private readonly bool _useColdStorage;
private readonly string _coldStoragePath; private readonly string _coldStoragePath;
// Debounce multiple updates towards the same file // Debounce multiple updates towards the same file
private readonly Dictionary<string, DateTime> _lastUpdateTimesUtc = new(1009, StringComparer.Ordinal); private readonly ConcurrentDictionary<string, DateTime> _lastUpdateTimesUtc = new(StringComparer.Ordinal);
private int _cleanupCounter = 0; private int _cleanupCounter = 0;
private const double _debounceTimeSecs = 90.0; private object _cleanupLockObj = new();
private const double _debounceTimeSecs = 900.0;
public ColdTouchHashService(ILogger<ColdTouchHashService> logger, IConfigurationService<StaticFilesServerConfiguration> configuration) public ColdTouchHashService(ILogger<ColdTouchHashService> logger, IConfigurationService<StaticFilesServerConfiguration> configuration)
{ {
@@ -37,31 +39,41 @@ public class ColdTouchHashService : ITouchHashService
public void TouchColdHash(string hash) public void TouchColdHash(string hash)
{ {
if (!_useColdStorage) if (!_useColdStorage)
return; return;
var nowUtc = DateTime.UtcNow; var nowUtc = DateTime.UtcNow;
// Clean up debounce dictionary regularly // Clean up debounce dictionary regularly
if (_cleanupCounter++ >= 1000) if (_cleanupCounter++ >= 1000)
{ {
foreach (var entry in _lastUpdateTimesUtc.Where(entry => (nowUtc - entry.Value).TotalSeconds >= _debounceTimeSecs).ToList())
_lastUpdateTimesUtc.Remove(entry.Key);
_cleanupCounter = 0; _cleanupCounter = 0;
} if (Monitor.TryEnter(_cleanupLockObj))
{
try
{
foreach (var entry in _lastUpdateTimesUtc.Where(entry => (nowUtc - entry.Value).TotalSeconds >= _debounceTimeSecs).ToList())
_lastUpdateTimesUtc.TryRemove(entry.Key, out _);
}
finally
{
Monitor.Exit(_cleanupLockObj);
}
}
}
// Ignore multiple updates within a 90 second window of the first // Ignore multiple updates within a time window of the first
if (_lastUpdateTimesUtc.TryGetValue(hash, out var lastUpdateTimeUtc) && (nowUtc - lastUpdateTimeUtc).TotalSeconds < _debounceTimeSecs) if (_lastUpdateTimesUtc.TryGetValue(hash, out var lastUpdateTimeUtc) && (nowUtc - lastUpdateTimeUtc).TotalSeconds < _debounceTimeSecs)
{ {
_logger.LogDebug($"Debounced touch for {hash}"); _logger.LogDebug($"Debounced touch for {hash}");
return; return;
} }
var fileInfo = FilePathUtil.GetFileInfoForHash(_coldStoragePath, hash); var fileInfo = FilePathUtil.GetFileInfoForHash(_coldStoragePath, hash);
if (fileInfo != null) if (fileInfo != null)
{ {
_logger.LogDebug($"Touching {fileInfo.Name}"); _logger.LogDebug($"Touching {fileInfo.Name}");
fileInfo.LastAccessTimeUtc = nowUtc; fileInfo.LastAccessTimeUtc = nowUtc;
_lastUpdateTimesUtc.TryAdd(hash, nowUtc); _lastUpdateTimesUtc.TryAdd(hash, nowUtc);
} }
} }

View File

@@ -101,7 +101,7 @@ public class ShardTouchMessageService : ITouchHashService
} }
if (hashes.Count > 0) if (hashes.Count > 0)
await SendTouches(hashes); await SendTouches(hashes);
await Task.Delay(TimeSpan.FromSeconds(30), ct).ConfigureAwait(false); await Task.Delay(TimeSpan.FromSeconds(60), ct).ConfigureAwait(false);
} }
catch (Exception e) catch (Exception e)
{ {