From 192ddfb1885bf95b96a04cbce2660b8548d5ba5a Mon Sep 17 00:00:00 2001 From: rootdarkarchon Date: Sat, 4 Nov 2023 03:35:19 +0100 Subject: [PATCH] optimize cacheservice --- .../Services/OnlineSyncedPairCacheService.cs | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/MareSynchronosServer/MareSynchronosServer/Services/OnlineSyncedPairCacheService.cs b/MareSynchronosServer/MareSynchronosServer/Services/OnlineSyncedPairCacheService.cs index d4ae49d..ff8bc9d 100644 --- a/MareSynchronosServer/MareSynchronosServer/Services/OnlineSyncedPairCacheService.cs +++ b/MareSynchronosServer/MareSynchronosServer/Services/OnlineSyncedPairCacheService.cs @@ -1,15 +1,14 @@ using MareSynchronosShared.Metrics; -using System.Collections.Concurrent; namespace MareSynchronosServer.Services; public class OnlineSyncedPairCacheService : IHostedService { private const int CleanupCount = 1; - private const int CacheCount = 500; + private const int CacheCount = 1000; private Task? _cleanUpTask; private readonly CancellationTokenSource _runnerCts = new(); - private readonly ConcurrentDictionary> _lastSeenCache = new(StringComparer.Ordinal); + private readonly Dictionary> _lastSeenCache = new(StringComparer.Ordinal); private readonly SemaphoreSlim _cleanupSemaphore = new(CleanupCount); private readonly SemaphoreSlim _cacheSemaphore = new(CacheCount); private readonly SemaphoreSlim _cacheAdditionSemaphore = new(1); @@ -120,9 +119,9 @@ public class OnlineSyncedPairCacheService : IHostedService { while (!ct.IsCancellationRequested) { - await Task.Delay(TimeSpan.FromSeconds(10), ct).ConfigureAwait(false); + await Task.Delay(TimeSpan.FromSeconds(60), ct).ConfigureAwait(false); - _logger.LogInformation("Cleaning up stale entries"); + _logger.LogInformation("Cleaning up stale entries: spin up"); try { @@ -144,33 +143,37 @@ public class OnlineSyncedPairCacheService : IHostedService { int entriesRemoved = 0; int playersRemoved = 0; - foreach (var playerCache in _lastSeenCache.ToDictionary(k => k.Key, k => k.Value, StringComparer.Ordinal)) - { - foreach (var cacheEntry in playerCache.Value.ToDictionary(k => k.Key, k => k.Value, StringComparer.Ordinal)) + _logger.LogInformation("Cleaning up stale entries: start"); + Parallel.ForEach(_lastSeenCache.ToDictionary(k => k.Key, k => k.Value, StringComparer.Ordinal), + playerCache => { - if (cacheEntry.Value < DateTime.UtcNow) + ct.ThrowIfCancellationRequested(); + + foreach (var cacheEntry in playerCache.Value.ToDictionary(k => k.Key, k => k.Value, StringComparer.Ordinal)) { - entriesRemoved++; - playerCache.Value.Remove(cacheEntry.Key); + if (cacheEntry.Value < DateTime.UtcNow) + { + Interlocked.Increment(ref entriesRemoved); + playerCache.Value.Remove(cacheEntry.Key); + } } - } - ct.ThrowIfCancellationRequested(); + ct.ThrowIfCancellationRequested(); - if (!playerCache.Value.Any()) - { - playersRemoved++; - _lastSeenCache.Remove(playerCache.Key, out _); - } - } + if (!playerCache.Value.Any()) + { + Interlocked.Increment(ref playersRemoved); + _lastSeenCache.Remove(playerCache.Key, out _); + } + }); - _logger.LogInformation("Cleaning up complete, removed {entries} individual entries and {players} players", entriesRemoved, playersRemoved); + _logger.LogInformation("Cleaning up stale entries: complete; removed {entries} individual entries and {players} players", entriesRemoved, playersRemoved); _mareMetrics.SetGaugeTo(MetricsAPI.GaugeUserPairCacheEntries, _lastSeenCache.Values.SelectMany(k => k.Keys).Count()); - _mareMetrics.SetGaugeTo(MetricsAPI.GaugeUserPairCacheUsers, _lastSeenCache.Keys.Count()); + _mareMetrics.SetGaugeTo(MetricsAPI.GaugeUserPairCacheUsers, _lastSeenCache.Keys.Count); } catch (Exception ex) { - _logger.LogWarning(ex, "Cleanup failed"); + _logger.LogWarning(ex, "Cleaning up stale entries: failed"); } } }