U4-4931 - fixing & refactoring
Conflicts: src/Umbraco.Core/Cache/DictionaryCacheProviderBase.cs src/Umbraco.Core/Cache/HttpRequestCacheProvider.cs src/Umbraco.Core/CacheHelper.cs src/Umbraco.Core/Umbraco.Core.csproj src/Umbraco.Tests/Cache/HttpRequestCacheProviderTests.cs
This commit is contained in:
@@ -3,7 +3,6 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
@@ -12,7 +11,8 @@ namespace Umbraco.Core.Cache
|
||||
// prefix cache keys so we know which one are ours
|
||||
protected const string CacheItemPrefix = "umbrtmche";
|
||||
|
||||
protected readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
|
||||
// an object that represent a value that has not been created yet
|
||||
protected readonly object ValueNotCreated = new object();
|
||||
|
||||
// manupulate the underlying cache entries
|
||||
// these *must* be called from within the appropriate locks
|
||||
@@ -21,15 +21,22 @@ namespace Umbraco.Core.Cache
|
||||
protected abstract void RemoveEntry(string key);
|
||||
protected abstract object GetEntry(string key);
|
||||
|
||||
// read-write lock the underlying cache
|
||||
protected abstract IDisposable ReadLock { get; }
|
||||
protected abstract IDisposable WriteLock { get; }
|
||||
|
||||
protected string GetCacheKey(string key)
|
||||
{
|
||||
return string.Format("{0}-{1}", CacheItemPrefix, key);
|
||||
}
|
||||
|
||||
protected object GetSafeLazyValue(Lazy<object> lazy)
|
||||
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
|
||||
@@ -42,7 +49,7 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
public virtual void ClearAllCache()
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
using (WriteLock)
|
||||
{
|
||||
foreach (var entry in GetDictionaryEntries()
|
||||
.ToArray())
|
||||
@@ -52,23 +59,24 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
public virtual void ClearCacheItem(string key)
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
var cacheKey = GetCacheKey(key);
|
||||
using (WriteLock)
|
||||
{
|
||||
var cacheKey = GetCacheKey(key);
|
||||
RemoveEntry(cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
using (WriteLock)
|
||||
{
|
||||
foreach (var entry in GetDictionaryEntries()
|
||||
.Where(x =>
|
||||
{
|
||||
// entry.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
var value = GetSafeLazyValue((Lazy<object>) x.Value); // return exceptions as null
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
return value == null || value.GetType().ToString().InvariantEquals(typeName);
|
||||
})
|
||||
.ToArray())
|
||||
@@ -79,7 +87,7 @@ namespace Umbraco.Core.Cache
|
||||
public virtual void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
var typeOfT = typeof(T);
|
||||
using (new WriteLock(Locker))
|
||||
using (WriteLock)
|
||||
{
|
||||
foreach (var entry in GetDictionaryEntries()
|
||||
.Where(x =>
|
||||
@@ -87,7 +95,8 @@ namespace Umbraco.Core.Cache
|
||||
// entry.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
// compare on exact type, don't use "is"
|
||||
var value = GetSafeLazyValue((Lazy<object>)x.Value); // return exceptions as null
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
return value == null || value.GetType() == typeOfT;
|
||||
})
|
||||
.ToArray())
|
||||
@@ -99,7 +108,7 @@ namespace Umbraco.Core.Cache
|
||||
{
|
||||
var typeOfT = typeof(T);
|
||||
var plen = CacheItemPrefix.Length + 1;
|
||||
using (new WriteLock(Locker))
|
||||
using (WriteLock)
|
||||
{
|
||||
foreach (var entry in GetDictionaryEntries()
|
||||
.Where(x =>
|
||||
@@ -107,7 +116,8 @@ namespace Umbraco.Core.Cache
|
||||
// entry.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
// compare on exact type, don't use "is"
|
||||
var value = GetSafeLazyValue((Lazy<object>)x.Value); // return exceptions as null
|
||||
// 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
|
||||
// run predicate on the 'public key' part only, ie without prefix
|
||||
@@ -120,7 +130,7 @@ namespace Umbraco.Core.Cache
|
||||
public virtual void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
var plen = CacheItemPrefix.Length + 1;
|
||||
using (new WriteLock(Locker))
|
||||
using (WriteLock)
|
||||
{
|
||||
foreach (var entry in GetDictionaryEntries()
|
||||
.Where(x => ((string)x.Key).Substring(plen).InvariantStartsWith(keyStartsWith))
|
||||
@@ -132,7 +142,7 @@ namespace Umbraco.Core.Cache
|
||||
public virtual void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
var plen = CacheItemPrefix.Length + 1;
|
||||
using (new WriteLock(Locker))
|
||||
using (WriteLock)
|
||||
{
|
||||
foreach (var entry in GetDictionaryEntries()
|
||||
.Where(x => Regex.IsMatch(((string)x.Key).Substring(plen), regexString))
|
||||
@@ -148,38 +158,43 @@ namespace Umbraco.Core.Cache
|
||||
public virtual IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith)
|
||||
{
|
||||
var plen = CacheItemPrefix.Length + 1;
|
||||
using (new ReadLock(Locker))
|
||||
IEnumerable<DictionaryEntry> entries;
|
||||
using (ReadLock)
|
||||
{
|
||||
return GetDictionaryEntries()
|
||||
entries = GetDictionaryEntries()
|
||||
.Where(x => ((string)x.Key).Substring(plen).InvariantStartsWith(keyStartsWith))
|
||||
.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();
|
||||
.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
|
||||
}
|
||||
|
||||
public virtual IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
|
||||
{
|
||||
const string prefix = CacheItemPrefix + "-";
|
||||
var plen = prefix.Length;
|
||||
using (new ReadLock(Locker))
|
||||
IEnumerable<DictionaryEntry> entries;
|
||||
using (ReadLock)
|
||||
{
|
||||
return GetDictionaryEntries()
|
||||
entries = GetDictionaryEntries()
|
||||
.Where(x => Regex.IsMatch(((string)x.Key).Substring(plen), regexString))
|
||||
.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();
|
||||
.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
|
||||
}
|
||||
|
||||
public virtual object GetCacheItem(string cacheKey)
|
||||
{
|
||||
cacheKey = GetCacheKey(cacheKey);
|
||||
using (new ReadLock(Locker))
|
||||
Lazy<object> result;
|
||||
using (ReadLock)
|
||||
{
|
||||
var result = GetEntry(cacheKey) as Lazy<object>; // null if key not found
|
||||
return result == null ? null : GetSafeLazyValue(result); // return exceptions as null
|
||||
result = GetEntry(cacheKey) as Lazy<object>; // null if key not found
|
||||
}
|
||||
return result == null ? null : GetSafeLazyValue(result); // return exceptions as null
|
||||
}
|
||||
|
||||
public abstract object GetCacheItem(string cacheKey, Func<object> getCacheItem);
|
||||
|
||||
Reference in New Issue
Block a user