U4-7816 The IsolatedCache instance in the RepositoryFactory differs from the ApplicationContext singleton instance

This commit is contained in:
Shannon
2016-01-22 16:37:47 +01:00
parent 9f365727e0
commit f78a425985
4 changed files with 61 additions and 66 deletions

View File

@@ -12,7 +12,7 @@ namespace Umbraco.Core.Cache
/// </remarks>
public class IsolatedRuntimeCache
{
private readonly Func<Type, IRuntimeCacheProvider> _cacheFactory;
internal Func<Type, IRuntimeCacheProvider> CacheFactory { get; set; }
/// <summary>
/// Constructor that allows specifying a factory for the type of runtime isolated cache to create
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Cache
/// <param name="cacheFactory"></param>
public IsolatedRuntimeCache(Func<Type, IRuntimeCacheProvider> cacheFactory)
{
_cacheFactory = cacheFactory;
CacheFactory = cacheFactory;
}
private readonly ConcurrentDictionary<Type, IRuntimeCacheProvider> _isolatedCache = new ConcurrentDictionary<Type, IRuntimeCacheProvider>();
@@ -32,7 +32,7 @@ namespace Umbraco.Core.Cache
/// <returns></returns>
public IRuntimeCacheProvider GetOrCreateCache<T>()
{
return _isolatedCache.GetOrAdd(typeof(T), type => _cacheFactory(type));
return _isolatedCache.GetOrAdd(typeof(T), type => CacheFactory(type));
}
/// <summary>
@@ -41,7 +41,7 @@ namespace Umbraco.Core.Cache
/// <returns></returns>
public IRuntimeCacheProvider GetOrCreateCache(Type type)
{
return _isolatedCache.GetOrAdd(type, t => _cacheFactory(t));
return _isolatedCache.GetOrAdd(type, t => CacheFactory(t));
}
/// <summary>

View File

@@ -18,12 +18,8 @@ namespace Umbraco.Core
/// </summary>
public class CacheHelper
{
private readonly IsolatedRuntimeCache _isolatedCacheManager;
private readonly ICacheProvider _requestCache;
private static readonly ICacheProvider NullRequestCache = new NullCacheProvider();
private readonly ICacheProvider _staticCache;
private static readonly ICacheProvider NullStaticCache = new NullCacheProvider();
private readonly IRuntimeCacheProvider _runtimeCache;
private static readonly IRuntimeCacheProvider NullRuntimeCache = new NullCacheProvider();
/// <summary>
@@ -90,45 +86,33 @@ namespace Umbraco.Core
if (staticCacheProvider == null) throw new ArgumentNullException("staticCacheProvider");
if (requestCacheProvider == null) throw new ArgumentNullException("requestCacheProvider");
if (isolatedCacheManager == null) throw new ArgumentNullException("isolatedCacheManager");
_runtimeCache = httpCacheProvider;
_staticCache = staticCacheProvider;
_requestCache = requestCacheProvider;
_isolatedCacheManager = isolatedCacheManager;
RuntimeCache = httpCacheProvider;
StaticCache = staticCacheProvider;
RequestCache = requestCacheProvider;
IsolatedRuntimeCache = isolatedCacheManager;
}
/// <summary>
/// Returns the current Request cache
/// </summary>
public ICacheProvider RequestCache
{
get { return _requestCache; }
}
public ICacheProvider RequestCache { get; internal set; }
/// <summary>
/// Returns the current Runtime cache
/// </summary>
public ICacheProvider StaticCache
{
get { return _staticCache; }
}
public ICacheProvider StaticCache { get; internal set; }
/// <summary>
/// Returns the current Runtime cache
/// </summary>
public IRuntimeCacheProvider RuntimeCache
{
get { return _runtimeCache; }
}
public IRuntimeCacheProvider RuntimeCache { get; internal set; }
/// <summary>
/// Returns the current Isolated Runtime cache manager
/// </summary>
public IsolatedRuntimeCache IsolatedRuntimeCache
{
get { return _isolatedCacheManager; }
}
#region Legacy Runtime/Http Cache accessors
public IsolatedRuntimeCache IsolatedRuntimeCache { get; internal set; }
#region Legacy Runtime/Http Cache accessors
/// <summary>
/// Clears the item in umbraco's runtime cache
@@ -137,8 +121,8 @@ namespace Umbraco.Core
[EditorBrowsable(EditorBrowsableState.Never)]
public void ClearAllCache()
{
_runtimeCache.ClearAllCache();
_isolatedCacheManager.ClearAllCaches();
RuntimeCache.ClearAllCache();
IsolatedRuntimeCache.ClearAllCaches();
}
/// <summary>
@@ -149,7 +133,7 @@ namespace Umbraco.Core
[EditorBrowsable(EditorBrowsableState.Never)]
public void ClearCacheItem(string key)
{
_runtimeCache.ClearCacheItem(key);
RuntimeCache.ClearCacheItem(key);
}
@@ -161,7 +145,7 @@ namespace Umbraco.Core
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public void ClearCacheObjectTypes(string typeName)
{
_runtimeCache.ClearCacheObjectTypes(typeName);
RuntimeCache.ClearCacheObjectTypes(typeName);
}
/// <summary>
@@ -171,7 +155,7 @@ namespace Umbraco.Core
[EditorBrowsable(EditorBrowsableState.Never)]
public void ClearCacheObjectTypes<T>()
{
_runtimeCache.ClearCacheObjectTypes<T>();
RuntimeCache.ClearCacheObjectTypes<T>();
}
/// <summary>
@@ -182,7 +166,7 @@ namespace Umbraco.Core
[EditorBrowsable(EditorBrowsableState.Never)]
public void ClearCacheByKeySearch(string keyStartsWith)
{
_runtimeCache.ClearCacheByKeySearch(keyStartsWith);
RuntimeCache.ClearCacheByKeySearch(keyStartsWith);
}
/// <summary>
@@ -193,14 +177,14 @@ namespace Umbraco.Core
[EditorBrowsable(EditorBrowsableState.Never)]
public void ClearCacheByKeyExpression(string regexString)
{
_runtimeCache.ClearCacheByKeyExpression(regexString);
RuntimeCache.ClearCacheByKeyExpression(regexString);
}
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
[EditorBrowsable(EditorBrowsableState.Never)]
public IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
{
return _runtimeCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
return RuntimeCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
}
/// <summary>
@@ -213,7 +197,7 @@ namespace Umbraco.Core
[EditorBrowsable(EditorBrowsableState.Never)]
public TT GetCacheItem<TT>(string cacheKey)
{
return _runtimeCache.GetCacheItem<TT>(cacheKey);
return RuntimeCache.GetCacheItem<TT>(cacheKey);
}
/// <summary>
@@ -227,7 +211,7 @@ namespace Umbraco.Core
[EditorBrowsable(EditorBrowsableState.Never)]
public TT GetCacheItem<TT>(string cacheKey, Func<TT> getCacheItem)
{
return _runtimeCache.GetCacheItem<TT>(cacheKey, getCacheItem);
return RuntimeCache.GetCacheItem<TT>(cacheKey, getCacheItem);
}
@@ -244,7 +228,7 @@ namespace Umbraco.Core
public TT GetCacheItem<TT>(string cacheKey,
TimeSpan timeout, Func<TT> getCacheItem)
{
return _runtimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout);
return RuntimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout);
}
@@ -263,7 +247,7 @@ namespace Umbraco.Core
CacheItemRemovedCallback refreshAction, TimeSpan timeout,
Func<TT> getCacheItem)
{
return _runtimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, removedCallback: refreshAction);
return RuntimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, removedCallback: refreshAction);
}
@@ -283,7 +267,7 @@ namespace Umbraco.Core
CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout,
Func<TT> getCacheItem)
{
return _runtimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, false, priority, refreshAction);
return RuntimeCache.GetCacheItem<TT>(cacheKey, getCacheItem, timeout, false, priority, refreshAction);
}
@@ -306,7 +290,7 @@ namespace Umbraco.Core
TimeSpan timeout,
Func<TT> getCacheItem)
{
var cache = _runtimeCache as HttpRuntimeCacheProvider;
var cache = RuntimeCache as HttpRuntimeCacheProvider;
if (cache != null)
{
var result = cache.GetCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, refreshAction, cacheDependency);
@@ -330,7 +314,7 @@ namespace Umbraco.Core
CacheDependency cacheDependency,
Func<TT> getCacheItem)
{
var cache = _runtimeCache as HttpRuntimeCacheProvider;
var cache = RuntimeCache as HttpRuntimeCacheProvider;
if (cache != null)
{
var result = cache.GetCacheItem(cacheKey, () => getCacheItem(), null, false, priority, null, cacheDependency);
@@ -352,7 +336,7 @@ namespace Umbraco.Core
CacheItemPriority priority,
Func<T> getCacheItem)
{
_runtimeCache.InsertCacheItem<T>(cacheKey, getCacheItem, priority: priority);
RuntimeCache.InsertCacheItem<T>(cacheKey, getCacheItem, priority: priority);
}
@@ -371,7 +355,7 @@ namespace Umbraco.Core
TimeSpan timeout,
Func<T> getCacheItem)
{
_runtimeCache.InsertCacheItem<T>(cacheKey, getCacheItem, timeout, priority: priority);
RuntimeCache.InsertCacheItem<T>(cacheKey, getCacheItem, timeout, priority: priority);
}
/// <summary>
@@ -390,7 +374,7 @@ namespace Umbraco.Core
TimeSpan timeout,
Func<T> getCacheItem)
{
var cache = _runtimeCache as HttpRuntimeCacheProvider;
var cache = RuntimeCache as HttpRuntimeCacheProvider;
if (cache != null)
{
cache.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, null, cacheDependency);
@@ -416,7 +400,7 @@ namespace Umbraco.Core
TimeSpan? timeout,
Func<T> getCacheItem)
{
var cache = _runtimeCache as HttpRuntimeCacheProvider;
var cache = RuntimeCache as HttpRuntimeCacheProvider;
if (cache != null)
{
cache.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, refreshAction, cacheDependency);

View File

@@ -31,29 +31,27 @@ namespace Umbraco.Core.Persistence
//if (sqlSyntax == null) throw new ArgumentNullException("sqlSyntax");
if (settings == null) throw new ArgumentNullException("settings");
_cacheHelper = cacheHelper;
_cacheHelper = cacheHelper;
//IMPORTANT: We will force the DeepCloneRuntimeCacheProvider to be used here which is a wrapper for the underlying
// runtime cache to ensure that anything that can be deep cloned in/out is done so, this also ensures that our tracks
// changes entities are reset.
if ((_cacheHelper.RuntimeCache is DeepCloneRuntimeCacheProvider) == false)
{
var originalHelper = cacheHelper;
_cacheHelper = new CacheHelper(
new DeepCloneRuntimeCacheProvider(originalHelper.RuntimeCache),
originalHelper.StaticCache,
originalHelper.RequestCache,
new IsolatedRuntimeCache(type =>
{
var cache = originalHelper.IsolatedRuntimeCache.GetOrCreateCache(type);
return (cache is DeepCloneRuntimeCacheProvider) == false
//wrap the original if it's not DeepCloneRuntimeCacheProvider
? new DeepCloneRuntimeCacheProvider(cache)
: cache;
}));
var origRuntimeCache = cacheHelper.RuntimeCache;
_cacheHelper.RuntimeCache = new DeepCloneRuntimeCacheProvider(origRuntimeCache);
}
//If the factory for isolated cache doesn't return DeepCloneRuntimeCacheProvider, then ensure it does
if (_cacheHelper.IsolatedRuntimeCache.CacheFactory.Method.ReturnType != typeof (DeepCloneRuntimeCacheProvider))
{
var origFactory = cacheHelper.IsolatedRuntimeCache.CacheFactory;
_cacheHelper.IsolatedRuntimeCache.CacheFactory = type =>
{
var cache = origFactory(type);
return new DeepCloneRuntimeCacheProvider(cache);
};
}
_noCache = CacheHelper.CreateDisabledCacheHelper();
_logger = logger;
_sqlSyntax = sqlSyntax;

View File

@@ -39,6 +39,7 @@ using Umbraco.Web.Scheduling;
using Umbraco.Web.UI.JavaScript;
using Umbraco.Web.WebApi;
using umbraco.BusinessLogic;
using Umbraco.Core.Cache;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Publishing;
@@ -240,7 +241,19 @@ namespace Umbraco.Web
protected override CacheHelper CreateApplicationCache()
{
//create a web-based cache helper
return new CacheHelper();
var cacheHelper = new CacheHelper(
//we need to have the dep clone runtime cache provider to ensure
//all entities are cached properly (cloned in and cloned out)
new DeepCloneRuntimeCacheProvider(new HttpRuntimeCacheProvider(HttpRuntime.Cache)),
new StaticCacheProvider(),
//we have no request based cache when not running in web-based context
new NullCacheProvider(),
new IsolatedRuntimeCache(type =>
//we need to have the dep clone runtime cache provider to ensure
//all entities are cached properly (cloned in and cloned out)
new DeepCloneRuntimeCacheProvider(new ObjectCacheRuntimeCacheProvider())));
return cacheHelper;
}
/// <summary>