From e45c500fa1d9eab6197d2cb8999715fc3374f246 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Tue, 19 Mar 2024 16:04:06 -0500 Subject: [PATCH] Changed how frequent maintenance removes expired items. --- src/Foundatio/Caching/InMemoryCacheClient.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Foundatio/Caching/InMemoryCacheClient.cs b/src/Foundatio/Caching/InMemoryCacheClient.cs index 09311779..45e5ea20 100644 --- a/src/Foundatio/Caching/InMemoryCacheClient.cs +++ b/src/Foundatio/Caching/InMemoryCacheClient.cs @@ -883,9 +883,14 @@ private async Task CompactAsync() (string Key, long LastAccessTicks, long InstanceNumber) oldest = (null, Int64.MaxValue, 0); foreach (var kvp in _memory) { - if (kvp.Value.LastAccessTicks < oldest.LastAccessTicks - || (kvp.Value.LastAccessTicks == oldest.LastAccessTicks && kvp.Value.InstanceNumber < oldest.InstanceNumber)) + bool isExpired = kvp.Value.ExpiresAt < SystemClock.UtcNow; + if (isExpired || + kvp.Value.LastAccessTicks < oldest.LastAccessTicks || + (kvp.Value.LastAccessTicks == oldest.LastAccessTicks && kvp.Value.InstanceNumber < oldest.InstanceNumber)) oldest = (kvp.Key, kvp.Value.LastAccessTicks, kvp.Value.InstanceNumber); + + if (isExpired) + break; } _logger.LogDebug("Removing cache entry {Key} due to cache exceeding max item count limit.", oldest); @@ -904,12 +909,15 @@ private async Task DoMaintenanceAsync() var utcNow = SystemClock.UtcNow.AddMilliseconds(50); + // Remove expired items and items that are infrequently accessed as they may be updated by add. + long lastAccessMaximumTicks = utcNow.AddMilliseconds(-300).Ticks; + try { foreach (var kvp in _memory.ToArray()) { - var expiresAt = kvp.Value.ExpiresAt; - if (expiresAt <= utcNow) + bool lastAccessTimeIsInfrequent = kvp.Value.LastAccessTicks < lastAccessMaximumTicks; + if (lastAccessTimeIsInfrequent && kvp.Value.ExpiresAt <= utcNow) { _logger.LogDebug("DoMaintenance: Removing expired key {Key}", kvp.Key); RemoveExpiredKey(kvp.Key);