Added missing locks and use timeout on all of them in ObjectCacheAppCache (#15902)

* Added missing locks, and ensure we have timeout on all of them

* Wrap the removable of objects from the hashset in a lock

* remove old comment

* Exit correct lock
This commit is contained in:
Bjarke Berg
2024-03-19 09:23:11 +00:00
committed by GitHub
parent 39085b9ad4
commit 1e69695650

View File

@@ -88,8 +88,10 @@ public class ObjectCacheAppCache : IAppPolicyCache, IDisposable
object[] entries;
try
{
_locker.EnterReadLock();
if (_locker.TryEnterReadLock(_readLockTimeout) is false)
{
throw new TimeoutException("Timeout exceeded to the memory cache when getting item");
}
entries = _keys.Where(predicate)
.Select(key => MemoryCache.Get(key))
.WhereNotNull()
@@ -125,11 +127,15 @@ public class ObjectCacheAppCache : IAppPolicyCache, IDisposable
if (result == null || SafeLazy.GetSafeLazyValue(result, true) == null)
{
result = SafeLazy.GetSafeLazy(factory);
MemoryCacheEntryOptions options = GetOptions(timeout, isSliding);
try
{
_locker.EnterWriteLock();
if (_locker.TryEnterWriteLock(_writeLockTimeout) is false)
{
throw new TimeoutException("Timeout exceeded to the memory cache when using factory to insert");
}
// NOTE: This does an add or update
MemoryCache.Set(key, result, options);
@@ -173,12 +179,26 @@ public class ObjectCacheAppCache : IAppPolicyCache, IDisposable
{
return; // do not store null values (backward compat)
}
MemoryCacheEntryOptions options = GetOptions(timeout, isSliding);
// NOTE: This does an add or update
MemoryCache.Set(key, result, options);
_keys.Add(key);
try
{
if (_locker.TryEnterWriteLock(_writeLockTimeout) is false)
{
throw new TimeoutException("Cannot insert value into cache, due to timeout for lock.");
}
// NOTE: This does an add or update
MemoryCache.Set(key, result, options);
_keys.Add(key);
}
finally
{
if (_locker.IsWriteLockHeld)
{
_locker.ExitWriteLock();
}
}
}
/// <inheritdoc />
@@ -348,6 +368,23 @@ public class ObjectCacheAppCache : IAppPolicyCache, IDisposable
}
// Ensure key is removed from set when evicted from cache
return options.RegisterPostEvictionCallback((key, _, _, _) => _keys.Remove((string)key));
return options.RegisterPostEvictionCallback((key, _, _, _) =>
{
try
{
if (_locker.TryEnterWriteLock(_writeLockTimeout) is false)
{
throw new TimeoutException("Timeout exceeded to the memory cache when using factory to insert");
}
_keys.Remove((string)key);
}
finally
{
if (_locker.IsWriteLockHeld)
{
_locker.ExitWriteLock();
}
}
});
}
}