U4-4931 - also for ObjectCacheRuntime provider

Conflicts:
	src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs
This commit is contained in:
Stephan
2014-07-10 10:24:04 +02:00
parent fd49c81940
commit e515b716f0

View File

@@ -19,11 +19,29 @@ namespace Umbraco.Core.Cache
private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
internal ObjectCache MemoryCache;
// an object that represent a value that has not been created yet
protected readonly object ValueNotCreated = new object();
public ObjectCacheRuntimeCacheProvider()
{
MemoryCache = new MemoryCache("in-memory");
}
protected object GetSafeLazyValue(Lazy<object> lazy, bool onlyIfValueIsCreated = false)
{
try
{
// if onlyIfValueIsCreated, do not trigger value creation
// must return something, though, to differenciate from null values
if (onlyIfValueIsCreated && lazy.IsValueCreated == false) return ValueNotCreated;
return lazy.Value;
}
catch
{
return null;
}
}
#region Clear
public virtual void ClearAllCache()
@@ -53,7 +71,8 @@ namespace Umbraco.Core.Cache
{
// x.Value is Lazy<object> and not null, its value may be null
// remove null values as well, does not hurt
var value = ((Lazy<object>) x.Value).Value;
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
return value == null || value.GetType().ToString().InvariantEquals(typeName);
})
.Select(x => x.Key)
@@ -72,7 +91,8 @@ namespace Umbraco.Core.Cache
{
// x.Value is Lazy<object> and not null, its value may be null
// remove null values as well, does not hurt
var value = ((Lazy<object>)x.Value).Value;
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
return value == null || value.GetType() == typeOfT;
})
.Select(x => x.Key)
@@ -91,7 +111,8 @@ namespace Umbraco.Core.Cache
{
// x.Value is Lazy<object> and not null, its value may be null
// remove null values as well, does not hurt
var value = ((Lazy<object>)x.Value).Value;
// get non-created as NonCreatedValue & exceptions as null
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
if (value == null) return true;
return value.GetType() == typeOfT
&& predicate(x.Key, (T) value);
@@ -132,35 +153,42 @@ namespace Umbraco.Core.Cache
public IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith)
{
KeyValuePair<string, object>[] entries;
using (new ReadLock(_locker))
{
return MemoryCache
entries = MemoryCache
.Where(x => x.Key.InvariantStartsWith(keyStartsWith))
.Select(x => ((Lazy<object>) x.Value).Value)
.Where(x => x != null) // backward compat, don't store null values in the cache
.ToList();
.ToArray(); // evaluate while locked
}
return entries
.Select(x => GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
.Where(x => x != null) // backward compat, don't store null values in the cache
.ToList();
}
public IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
{
KeyValuePair<string, object>[] entries;
using (new ReadLock(_locker))
{
return MemoryCache
entries = MemoryCache
.Where(x => Regex.IsMatch(x.Key, regexString))
.Select(x => ((Lazy<object>) x.Value).Value)
.Where(x => x != null) // backward compat, don't store null values in the cache
.ToList();
.ToArray(); // evaluate while locked
}
return entries
.Select(x => GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
.Where(x => x != null) // backward compat, don't store null values in the cache
.ToList();
}
public object GetCacheItem(string cacheKey)
{
Lazy<object> result;
using (new ReadLock(_locker))
{
var result = MemoryCache.Get(cacheKey) as Lazy<object>;
return result == null ? null : result.Value;
result = MemoryCache.Get(cacheKey) as Lazy<object>; // null if key not found
}
return result == null ? null : GetSafeLazyValue(result); // return exceptions as null
}
public object GetCacheItem(string cacheKey, Func<object> getCacheItem)
@@ -177,12 +205,12 @@ namespace Umbraco.Core.Cache
using (var lck = new UpgradeableReadLock(_locker))
{
result = MemoryCache.Get(cacheKey) as Lazy<object>;
if (result == null || (result.IsValueCreated && result.Value == null))
if (result == null || GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
{
lck.UpgradeToWriteLock();
result = new Lazy<object>(getCacheItem);
var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles);
lck.UpgradeToWriteLock();
MemoryCache.Set(cacheKey, result, policy);
}
}