diff --git a/src/Umbraco.Core/ApplicationContext.cs b/src/Umbraco.Core/ApplicationContext.cs index a05abe2a50..e47ef04650 100644 --- a/src/Umbraco.Core/ApplicationContext.cs +++ b/src/Umbraco.Core/ApplicationContext.cs @@ -406,7 +406,8 @@ namespace Umbraco.Core //clear the cache if (ApplicationCache != null) { - ApplicationCache.ClearAllCache(); + ApplicationCache.RuntimeCache.ClearAllCache(); + ApplicationCache.IsolatedRuntimeCache.ClearAllCaches(); } //reset all resolvers ResolverCollection.ResetAll(); diff --git a/src/Umbraco.Core/Cache/CacheKeys.cs b/src/Umbraco.Core/Cache/CacheKeys.cs index 88d570beff..0c1a202b66 100644 --- a/src/Umbraco.Core/Cache/CacheKeys.cs +++ b/src/Umbraco.Core/Cache/CacheKeys.cs @@ -1,8 +1,9 @@ using System; +using System.ComponentModel; +using Umbraco.Core.CodeAnnotations; namespace Umbraco.Core.Cache { - /// /// Constants storing cache keys used in caching /// @@ -12,52 +13,78 @@ namespace Umbraco.Core.Cache public const string ApplicationsCacheKey = "ApplicationCache"; [Obsolete("This is no longer used and will be removed from the codebase in the future")] + [EditorBrowsable(EditorBrowsableState.Never)] public const string UserTypeCacheKey = "UserTypeCache"; + [Obsolete("This is no longer used and will be removed from the codebase in the future - it is referenced but no cache is stored against this key")] + [EditorBrowsable(EditorBrowsableState.Never)] public const string ContentItemCacheKey = "contentItem"; + [UmbracoWillObsolete("This cache key is only used for the legacy 'library' caching, remove in v8")] public const string MediaCacheKey = "UL_GetMedia"; public const string MacroXsltCacheKey = "macroXslt_"; + + [UmbracoWillObsolete("This cache key is only used for legacy business logic caching, remove in v8")] public const string MacroCacheKey = "UmbracoMacroCache"; + public const string MacroHtmlCacheKey = "macroHtml_"; public const string MacroControlCacheKey = "macroControl_"; public const string MacroHtmlDateAddedCacheKey = "macroHtml_DateAdded_"; public const string MacroControlDateAddedCacheKey = "macroControl_DateAdded_"; + [UmbracoWillObsolete("This cache key is only used for legacy 'library' member caching, remove in v8")] public const string MemberLibraryCacheKey = "UL_GetMember"; + + [UmbracoWillObsolete("This cache key is only used for legacy business logic caching, remove in v8")] public const string MemberBusinessLogicCacheKey = "MemberCacheItem_"; - + + [UmbracoWillObsolete("This cache key is only used for legacy template business logic caching, remove in v8")] public const string TemplateFrontEndCacheKey = "template"; [Obsolete("This is no longer used and will be removed from the codebase in the future")] + [EditorBrowsable(EditorBrowsableState.Never)] public const string TemplateBusinessLogicCacheKey = "UmbracoTemplateCache"; + [Obsolete("This is no longer used and will be removed from the codebase in the future")] + [EditorBrowsable(EditorBrowsableState.Never)] public const string UserContextCacheKey = "UmbracoUserContext"; + public const string UserContextTimeoutCacheKey = "UmbracoUserContextTimeout"; [Obsolete("This is no longer used and will be removed from the codebase in the future")] + [EditorBrowsable(EditorBrowsableState.Never)] public const string UserCacheKey = "UmbracoUser"; public const string UserPermissionsCacheKey = "UmbracoUserPermissions"; + [UmbracoWillObsolete("This cache key is only used for legacy business logic caching, remove in v8")] public const string ContentTypeCacheKey = "UmbracoContentType"; + [UmbracoWillObsolete("This cache key is only used for legacy business logic caching, remove in v8")] public const string ContentTypePropertiesCacheKey = "ContentType_PropertyTypes_Content:"; + [UmbracoWillObsolete("This cache key is only used for legacy business logic caching, remove in v8")] public const string PropertyTypeCacheKey = "UmbracoPropertyTypeCache"; [Obsolete("This is no longer used and will be removed from the codebase in the future")] + [EditorBrowsable(EditorBrowsableState.Never)] public const string LanguageCacheKey = "UmbracoLanguageCache"; [Obsolete("This is no longer used and will be removed from the codebase in the future")] + [EditorBrowsable(EditorBrowsableState.Never)] public const string DomainCacheKey = "UmbracoDomainList"; [Obsolete("This is no longer used and will be removed from the codebase in the future")] + [EditorBrowsable(EditorBrowsableState.Never)] public const string StylesheetCacheKey = "UmbracoStylesheet"; + [Obsolete("This is no longer used and will be removed from the codebase in the future")] + [EditorBrowsable(EditorBrowsableState.Never)] public const string StylesheetPropertyCacheKey = "UmbracoStylesheetProperty"; + [Obsolete("This is no longer used and will be removed from the codebase in the future")] + [EditorBrowsable(EditorBrowsableState.Never)] public const string DataTypeCacheKey = "UmbracoDataTypeDefinition"; public const string DataTypePreValuesCacheKey = "UmbracoPreVal"; diff --git a/src/Umbraco.Core/Cache/CacheRefresherBase.cs b/src/Umbraco.Core/Cache/CacheRefresherBase.cs index 2931805b08..2ee7873ad0 100644 --- a/src/Umbraco.Core/Cache/CacheRefresherBase.cs +++ b/src/Umbraco.Core/Cache/CacheRefresherBase.cs @@ -2,6 +2,7 @@ using Umbraco.Core.Events; using Umbraco.Core.Sync; using umbraco.interfaces; +using Umbraco.Core.Models.EntityBase; namespace Umbraco.Core.Cache { @@ -63,5 +64,15 @@ namespace Umbraco.Core.Cache { OnCacheUpdated(Instance, new CacheRefresherEventArgs(id, MessageType.RefreshById)); } + + /// + /// Clears the cache for all repository entities of this type + /// + /// + protected void ClearAllCacheByRepositoryEntityType() + where TEntity : class, IAggregateRoot + { + ApplicationContext.Current.ApplicationCache.IsolatedRuntimeCache.ClearCache(); + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Cache/IsolatedRuntimeCache.cs b/src/Umbraco.Core/Cache/IsolatedRuntimeCache.cs new file mode 100644 index 0000000000..103f90345d --- /dev/null +++ b/src/Umbraco.Core/Cache/IsolatedRuntimeCache.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Concurrent; + +namespace Umbraco.Core.Cache +{ + /// + /// Used to get/create/manipulate isolated runtime cache + /// + /// + /// This is useful for repository level caches to ensure that cache lookups by key are fast so + /// that the repository doesn't need to search through all keys on a global scale. + /// + public class IsolatedRuntimeCache + { + private readonly Func _cacheFactory; + + /// + /// Constructor that allows specifying a factory for the type of runtime isolated cache to create + /// + /// + public IsolatedRuntimeCache(Func cacheFactory) + { + _cacheFactory = cacheFactory; + } + + private readonly ConcurrentDictionary _isolatedCache = new ConcurrentDictionary(); + + /// + /// Returns an isolated runtime cache for a given type + /// + /// + /// + public IRuntimeCacheProvider GetOrCreateCache() + { + return _isolatedCache.GetOrAdd(typeof(T), type => _cacheFactory(type)); + } + + /// + /// Returns an isolated runtime cache for a given type + /// + /// + public IRuntimeCacheProvider GetOrCreateCache(Type type) + { + return _isolatedCache.GetOrAdd(type, t => _cacheFactory(t)); + } + + /// + /// Tries to get a cache by the type specified + /// + /// + /// + public Attempt GetCache() + { + IRuntimeCacheProvider cache; + if (_isolatedCache.TryGetValue(typeof(T), out cache)) + { + return Attempt.Succeed(cache); + } + return Attempt.Fail(); + } + + /// + /// Clears all values inside this isolated runtime cache + /// + /// + /// + public void ClearCache() + { + IRuntimeCacheProvider cache; + if (_isolatedCache.TryGetValue(typeof(T), out cache)) + { + cache.ClearAllCache(); + } + } + + /// + /// Clears all of the isolated caches + /// + public void ClearAllCaches() + { + foreach (var key in _isolatedCache.Keys) + { + IRuntimeCacheProvider cache; + if (_isolatedCache.TryRemove(key, out cache)) + { + cache.ClearAllCache(); + } + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/CacheHelper.cs b/src/Umbraco.Core/CacheHelper.cs index 44a0a35f2b..303cf234fd 100644 --- a/src/Umbraco.Core/CacheHelper.cs +++ b/src/Umbraco.Core/CacheHelper.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Text.RegularExpressions; @@ -17,14 +18,13 @@ namespace Umbraco.Core /// public class CacheHelper { - private readonly bool _enableCache; + private readonly IsolatedRuntimeCache _isolatedCacheManager; private readonly ICacheProvider _requestCache; - private readonly ICacheProvider _nullRequestCache = new NullCacheProvider(); + private static readonly ICacheProvider NullRequestCache = new NullCacheProvider(); private readonly ICacheProvider _staticCache; - private readonly ICacheProvider _nullStaticCache = new NullCacheProvider(); + private static readonly ICacheProvider NullStaticCache = new NullCacheProvider(); private readonly IRuntimeCacheProvider _runtimeCache; - private readonly IRuntimeCacheProvider _nullRuntimeCache = new NullCacheProvider(); - private readonly ConcurrentDictionary _isolatedCache = new ConcurrentDictionary(); + private static readonly IRuntimeCacheProvider NullRuntimeCache = new NullCacheProvider(); /// /// Creates a cache helper with disabled caches @@ -35,7 +35,7 @@ namespace Umbraco.Core /// public static CacheHelper CreateDisabledCacheHelper() { - return new CacheHelper(null, null, null, false); + return new CacheHelper(NullRuntimeCache, NullStaticCache, NullRequestCache, new IsolatedRuntimeCache(t => NullRuntimeCache)); } /// @@ -45,7 +45,8 @@ namespace Umbraco.Core : this( new HttpRuntimeCacheProvider(HttpRuntime.Cache), new StaticCacheProvider(), - new HttpRequestCacheProvider()) + new HttpRequestCacheProvider(), + new IsolatedRuntimeCache(t => new ObjectCacheRuntimeCacheProvider())) { } @@ -57,83 +58,58 @@ namespace Umbraco.Core : this( new HttpRuntimeCacheProvider(cache), new StaticCacheProvider(), - new HttpRequestCacheProvider()) + new HttpRequestCacheProvider(), + new IsolatedRuntimeCache(t => new ObjectCacheRuntimeCacheProvider())) { } - /// - /// Initializes a new instance based on the provided providers - /// - /// - /// - /// + [Obsolete("Use the constructor the specifies all dependencies")] + [EditorBrowsable(EditorBrowsableState.Never)] public CacheHelper( IRuntimeCacheProvider httpCacheProvider, ICacheProvider staticCacheProvider, ICacheProvider requestCacheProvider) - : this(httpCacheProvider, staticCacheProvider, requestCacheProvider, true) + : this(httpCacheProvider, staticCacheProvider, requestCacheProvider, new IsolatedRuntimeCache(t => new ObjectCacheRuntimeCacheProvider())) { } - /// - /// Private ctor used for creating a disabled cache helper - /// - /// - /// - /// - /// - private CacheHelper( + /// + /// Initializes a new instance based on the provided providers + /// + /// + /// + /// + /// + public CacheHelper( IRuntimeCacheProvider httpCacheProvider, ICacheProvider staticCacheProvider, - ICacheProvider requestCacheProvider, - bool enableCache) + ICacheProvider requestCacheProvider, + IsolatedRuntimeCache isolatedCacheManager) { - if (enableCache) - { - _runtimeCache = httpCacheProvider; - _staticCache = staticCacheProvider; - _requestCache = requestCacheProvider; - } - else - { - _runtimeCache = null; - _staticCache = null; - _requestCache = null; - } - - _enableCache = enableCache; + if (httpCacheProvider == null) throw new ArgumentNullException("httpCacheProvider"); + 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; } /// - /// Returns an isolated runtime cache for a given type - /// - /// - /// - /// - /// This is useful for repository level caches to ensure that cache lookups by key are fast so - /// that the repository doesn't need to search through all keys on a global scale. - /// - public IRuntimeCacheProvider GetIsolatedRuntimeCache() - { - return _enableCache == false - ? _nullRuntimeCache - : _isolatedCache.GetOrAdd(typeof (T), type => new ObjectCacheRuntimeCacheProvider()); - } - - /// /// Returns the current Request cache /// public ICacheProvider RequestCache { - get { return _enableCache ? _requestCache : _nullRequestCache; } + get { return _requestCache; } } - + /// /// Returns the current Runtime cache /// public ICacheProvider StaticCache { - get { return _enableCache ? _staticCache : _nullStaticCache; } + get { return _staticCache; } } /// @@ -141,8 +117,16 @@ namespace Umbraco.Core /// public IRuntimeCacheProvider RuntimeCache { - get { return _enableCache ? _runtimeCache : _nullRuntimeCache; } + get { return _runtimeCache; } } + + /// + /// Returns the current Isolated Runtime cache manager + /// + public IsolatedRuntimeCache IsolatedRuntimeCache + { + get { return _isolatedCacheManager; } + } #region Legacy Runtime/Http Cache accessors @@ -150,16 +134,11 @@ namespace Umbraco.Core /// Clears the item in umbraco's runtime cache /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] + [EditorBrowsable(EditorBrowsableState.Never)] public void ClearAllCache() { - if (_enableCache == false) - { - _nullRuntimeCache.ClearAllCache(); - } - else - { - _runtimeCache.ClearAllCache(); - } + _runtimeCache.ClearAllCache(); + _isolatedCacheManager.ClearAllCaches(); } /// @@ -167,16 +146,10 @@ namespace Umbraco.Core /// /// Key [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] + [EditorBrowsable(EditorBrowsableState.Never)] public void ClearCacheItem(string key) { - if (_enableCache == false) - { - _nullRuntimeCache.ClearCacheItem(key); - } - else - { - _runtimeCache.ClearCacheItem(key); - } + _runtimeCache.ClearCacheItem(key); } @@ -188,30 +161,17 @@ namespace Umbraco.Core [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] public void ClearCacheObjectTypes(string typeName) { - if (_enableCache == false) - { - _nullRuntimeCache.ClearCacheObjectTypes(typeName); - } - else - { - _runtimeCache.ClearCacheObjectTypes(typeName); - } + _runtimeCache.ClearCacheObjectTypes(typeName); } /// /// Clears all objects in the System.Web.Cache with the System.Type specified /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] + [EditorBrowsable(EditorBrowsableState.Never)] public void ClearCacheObjectTypes() { - if (_enableCache == false) - { - _nullRuntimeCache.ClearCacheObjectTypes(); - } - else - { - _runtimeCache.ClearCacheObjectTypes(); - } + _runtimeCache.ClearCacheObjectTypes(); } /// @@ -219,16 +179,10 @@ namespace Umbraco.Core /// /// The start of the key [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] + [EditorBrowsable(EditorBrowsableState.Never)] public void ClearCacheByKeySearch(string keyStartsWith) { - if (_enableCache == false) - { - _nullRuntimeCache.ClearCacheByKeySearch(keyStartsWith); - } - else - { - _runtimeCache.ClearCacheByKeySearch(keyStartsWith); - } + _runtimeCache.ClearCacheByKeySearch(keyStartsWith); } /// @@ -236,29 +190,17 @@ namespace Umbraco.Core /// /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] + [EditorBrowsable(EditorBrowsableState.Never)] public void ClearCacheByKeyExpression(string regexString) { - if (_enableCache == false) - { - _nullRuntimeCache.ClearCacheByKeyExpression(regexString); - } - else - { - _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 GetCacheItemsByKeySearch(string keyStartsWith) { - if (_enableCache == false) - { - return _nullRuntimeCache.GetCacheItemsByKeySearch(keyStartsWith); - } - else - { - return _runtimeCache.GetCacheItemsByKeySearch(keyStartsWith); - } + return _runtimeCache.GetCacheItemsByKeySearch(keyStartsWith); } /// @@ -268,16 +210,10 @@ namespace Umbraco.Core /// /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] + [EditorBrowsable(EditorBrowsableState.Never)] public TT GetCacheItem(string cacheKey) { - if (_enableCache == false) - { - return _nullRuntimeCache.GetCacheItem(cacheKey); - } - else - { - return _runtimeCache.GetCacheItem(cacheKey); - } + return _runtimeCache.GetCacheItem(cacheKey); } /// @@ -288,16 +224,11 @@ namespace Umbraco.Core /// /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] + [EditorBrowsable(EditorBrowsableState.Never)] public TT GetCacheItem(string cacheKey, Func getCacheItem) { - if (_enableCache == false) - { - return _nullRuntimeCache.GetCacheItem(cacheKey, getCacheItem); - } - else - { - return _runtimeCache.GetCacheItem(cacheKey, getCacheItem); - } + return _runtimeCache.GetCacheItem(cacheKey, getCacheItem); + } /// @@ -309,17 +240,12 @@ namespace Umbraco.Core /// /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] + [EditorBrowsable(EditorBrowsableState.Never)] public TT GetCacheItem(string cacheKey, TimeSpan timeout, Func getCacheItem) { - if (_enableCache == false) - { - return _nullRuntimeCache.GetCacheItem(cacheKey, getCacheItem, timeout); - } - else - { - return _runtimeCache.GetCacheItem(cacheKey, getCacheItem, timeout); - } + return _runtimeCache.GetCacheItem(cacheKey, getCacheItem, timeout); + } /// @@ -332,18 +258,13 @@ namespace Umbraco.Core /// /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] + [EditorBrowsable(EditorBrowsableState.Never)] public TT GetCacheItem(string cacheKey, CacheItemRemovedCallback refreshAction, TimeSpan timeout, Func getCacheItem) { - if (!_enableCache) - { - return _nullRuntimeCache.GetCacheItem(cacheKey, getCacheItem, timeout, removedCallback: refreshAction); - } - else - { - return _runtimeCache.GetCacheItem(cacheKey, getCacheItem, timeout, removedCallback: refreshAction); - } + return _runtimeCache.GetCacheItem(cacheKey, getCacheItem, timeout, removedCallback: refreshAction); + } /// @@ -357,18 +278,13 @@ namespace Umbraco.Core /// /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] + [EditorBrowsable(EditorBrowsableState.Never)] public TT GetCacheItem(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout, Func getCacheItem) { - if (_enableCache == false) - { - return _nullRuntimeCache.GetCacheItem(cacheKey, getCacheItem, timeout, false, priority, refreshAction); - } - else - { - return _runtimeCache.GetCacheItem(cacheKey, getCacheItem, timeout, false, priority, refreshAction); - } + return _runtimeCache.GetCacheItem(cacheKey, getCacheItem, timeout, false, priority, refreshAction); + } /// @@ -390,20 +306,13 @@ namespace Umbraco.Core TimeSpan timeout, Func getCacheItem) { - if (_enableCache == false) + var cache = _runtimeCache as HttpRuntimeCacheProvider; + if (cache != null) { - return _nullRuntimeCache.GetCacheItem(cacheKey, getCacheItem, timeout, false, priority, refreshAction, null); - } - else - { - var cache = _runtimeCache as HttpRuntimeCacheProvider; - if (cache != null) - { - var result = cache.GetCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, refreshAction, cacheDependency); - return result == null ? default(TT) : result.TryConvertTo().Result; - } - throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider)); + var result = cache.GetCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, refreshAction, cacheDependency); + return result == null ? default(TT) : result.TryConvertTo().Result; } + throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider)); } /// @@ -421,20 +330,13 @@ namespace Umbraco.Core CacheDependency cacheDependency, Func getCacheItem) { - if (!_enableCache) + var cache = _runtimeCache as HttpRuntimeCacheProvider; + if (cache != null) { - return _nullRuntimeCache.GetCacheItem(cacheKey, getCacheItem, null, false, priority, null, null); - } - else - { - var cache = _runtimeCache as HttpRuntimeCacheProvider; - if (cache != null) - { - var result = cache.GetCacheItem(cacheKey, () => getCacheItem(), null, false, priority, null, cacheDependency); - return result == null ? default(TT) : result.TryConvertTo().Result; - } - throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider)); + var result = cache.GetCacheItem(cacheKey, () => getCacheItem(), null, false, priority, null, cacheDependency); + return result == null ? default(TT) : result.TryConvertTo().Result; } + throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider)); } /// @@ -444,18 +346,14 @@ namespace Umbraco.Core /// /// /// + [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] + [EditorBrowsable(EditorBrowsableState.Never)] public void InsertCacheItem(string cacheKey, CacheItemPriority priority, Func getCacheItem) { - if (_enableCache == false) - { - _nullRuntimeCache.InsertCacheItem(cacheKey, getCacheItem, priority: priority); - } - else - { - _runtimeCache.InsertCacheItem(cacheKey, getCacheItem, priority: priority); - } + _runtimeCache.InsertCacheItem(cacheKey, getCacheItem, priority: priority); + } /// @@ -466,19 +364,14 @@ namespace Umbraco.Core /// /// This will set an absolute expiration from now until the timeout /// + [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] + [EditorBrowsable(EditorBrowsableState.Never)] public void InsertCacheItem(string cacheKey, CacheItemPriority priority, TimeSpan timeout, Func getCacheItem) { - if (_enableCache == false) - { - _nullRuntimeCache.InsertCacheItem(cacheKey, getCacheItem, timeout, priority: priority); - } - else - { - _runtimeCache.InsertCacheItem(cacheKey, getCacheItem, timeout, priority: priority); - } + _runtimeCache.InsertCacheItem(cacheKey, getCacheItem, timeout, priority: priority); } /// @@ -497,19 +390,12 @@ namespace Umbraco.Core TimeSpan timeout, Func getCacheItem) { - if (_enableCache == false) + var cache = _runtimeCache as HttpRuntimeCacheProvider; + if (cache != null) { - _nullRuntimeCache.InsertCacheItem(cacheKey, getCacheItem, timeout, priority: priority, dependentFiles:null); - } - else - { - var cache = _runtimeCache as HttpRuntimeCacheProvider; - if (cache != null) - { - cache.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, null, cacheDependency); - } - throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider)); + cache.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, null, cacheDependency); } + throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider)); } /// @@ -530,19 +416,12 @@ namespace Umbraco.Core TimeSpan? timeout, Func getCacheItem) { - if (_enableCache == false) + var cache = _runtimeCache as HttpRuntimeCacheProvider; + if (cache != null) { - _nullRuntimeCache.InsertCacheItem(cacheKey, getCacheItem, timeout, false, priority, refreshAction, null); - } - else - { - var cache = _runtimeCache as HttpRuntimeCacheProvider; - if (cache != null) - { - cache.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, refreshAction, cacheDependency); - } - throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider)); + cache.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, refreshAction, cacheDependency); } + throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider)); } #endregion diff --git a/src/Umbraco.Core/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs index b4e3d06273..17f909da8a 100644 --- a/src/Umbraco.Core/CoreBootManager.cs +++ b/src/Umbraco.Core/CoreBootManager.cs @@ -188,10 +188,16 @@ namespace Umbraco.Core protected virtual CacheHelper CreateApplicationCache() { var cacheHelper = new CacheHelper( - new ObjectCacheRuntimeCacheProvider(), + //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()), new StaticCacheProvider(), //we have no request based cache when not running in web-based context - new NullCacheProvider()); + 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; } diff --git a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs index 859c4e7ae7..244deaccb8 100644 --- a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs @@ -24,17 +24,15 @@ namespace Umbraco.Core.Persistence.Repositories /// internal class DataTypeDefinitionRepository : PetaPocoRepositoryBase, IDataTypeDefinitionRepository { - private readonly CacheHelper _cacheHelper; private readonly IContentTypeRepository _contentTypeRepository; private readonly DataTypePreValueRepository _preValRepository; - public DataTypeDefinitionRepository(IDatabaseUnitOfWork work, CacheHelper cache, CacheHelper cacheHelper, ILogger logger, ISqlSyntaxProvider sqlSyntax, + public DataTypeDefinitionRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IContentTypeRepository contentTypeRepository) : base(work, cache, logger, sqlSyntax) { - _cacheHelper = cacheHelper; _contentTypeRepository = contentTypeRepository; - _preValRepository = new DataTypePreValueRepository(work, CacheHelper.CreateDisabledCacheHelper(), logger, sqlSyntax); + _preValRepository = new DataTypePreValueRepository(work, CacheHelper.CreateDisabledCacheHelper(), logger, sqlSyntax); } #region Overrides of RepositoryBase @@ -231,7 +229,7 @@ AND umbracoNode.id <> @id", //NOTE: This is a special case, we need to clear the custom cache for pre-values here so they are not stale if devs // are querying for them in the Saved event (before the distributed call cache is clearing it) - _cacheHelper.RuntimeCache.ClearCacheItem(GetPrefixedCacheKey(entity.Id)); + RuntimeCache.ClearCacheItem(GetPrefixedCacheKey(entity.Id)); entity.ResetDirtyProperties(); } @@ -270,7 +268,7 @@ AND umbracoNode.id <> @id", public PreValueCollection GetPreValuesCollectionByDataTypeId(int dataTypeId) { - var cached = _cacheHelper.RuntimeCache.GetCacheItemsByKeySearch(GetPrefixedCacheKey(dataTypeId)); + var cached = RuntimeCache.GetCacheItemsByKeySearch(GetPrefixedCacheKey(dataTypeId)); if (cached != null && cached.Any()) { //return from the cache, ensure it's a cloned result @@ -289,7 +287,7 @@ AND umbracoNode.id <> @id", { //We need to see if we can find the cached PreValueCollection based on the cache key above - var cached = _cacheHelper.RuntimeCache.GetCacheItemsByKeyExpression(GetCacheKeyRegex(preValueId)); + var cached = RuntimeCache.GetCacheItemsByKeyExpression(GetCacheKeyRegex(preValueId)); if (cached != null && cached.Any()) { //return from the cache @@ -408,7 +406,7 @@ AND umbracoNode.id <> @id", + string.Join(",", collection.FormatAsDictionary().Select(x => x.Value.Id).ToArray()); //store into cache - _cacheHelper.RuntimeCache.InsertCacheItem(key, () => collection, + RuntimeCache.InsertCacheItem(key, () => collection, //30 mins new TimeSpan(0, 0, 30), //sliding is true diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs index 264409ddf4..40121223a2 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs @@ -20,13 +20,9 @@ namespace Umbraco.Core.Persistence.Repositories internal class MemberGroupRepository : PetaPocoRepositoryBase, IMemberGroupRepository { - private readonly CacheHelper _cacheHelper; - - public MemberGroupRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, CacheHelper cacheHelper) + public MemberGroupRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax) : base(work, cache, logger, sqlSyntax) { - if (cacheHelper == null) throw new ArgumentNullException("cacheHelper"); - _cacheHelper = cacheHelper; } private readonly MemberGroupFactory _modelFactory = new MemberGroupFactory(); @@ -135,7 +131,7 @@ namespace Umbraco.Core.Persistence.Repositories public IMemberGroup GetByName(string name) { - return _cacheHelper.RuntimeCache.GetCacheItem( + return RuntimeCache.GetCacheItem( string.Format("{0}.{1}", typeof (IMemberGroup).FullName, name), () => { diff --git a/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs index 0463312982..aa671dccec 100644 --- a/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs @@ -26,13 +26,14 @@ namespace Umbraco.Core.Persistence.Repositories where TEntity : class, IAggregateRoot { private readonly IDatabaseUnitOfWork _unitOfWork; - private readonly CacheHelper _cache; + private readonly IRuntimeCacheProvider _runtimeCache; private readonly ISqlSyntaxProvider _sqlSyntax; internal PermissionRepository(IDatabaseUnitOfWork unitOfWork, CacheHelper cache, ISqlSyntaxProvider sqlSyntax) { _unitOfWork = unitOfWork; - _cache = cache; + //Make this repository use an isolated cache + _runtimeCache = cache.IsolatedRuntimeCache.GetOrCreateCache(); _sqlSyntax = sqlSyntax; } @@ -45,7 +46,7 @@ namespace Umbraco.Core.Persistence.Repositories public IEnumerable GetUserPermissionsForEntities(int userId, params int[] entityIds) { var entityIdKey = string.Join(",", entityIds.Select(x => x.ToString(CultureInfo.InvariantCulture))); - return _cache.RuntimeCache.GetCacheItem>( + return _runtimeCache.GetCacheItem>( string.Format("{0}{1}{2}", CacheKeys.UserPermissionsCacheKey, userId, entityIdKey), () => { diff --git a/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs index 2ce3537bb9..da02dcf3b4 100644 --- a/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs @@ -89,7 +89,7 @@ namespace Umbraco.Core.Persistence.Repositories /// protected override IRuntimeCacheProvider RuntimeCache { - get { return RepositoryCache.GetIsolatedRuntimeCache(); } + get { return RepositoryCache.IsolatedRuntimeCache.GetOrCreateCache(); } } /// diff --git a/src/Umbraco.Core/Persistence/RepositoryFactory.cs b/src/Umbraco.Core/Persistence/RepositoryFactory.cs index d99ae8f464..e148bbe2fe 100644 --- a/src/Umbraco.Core/Persistence/RepositoryFactory.cs +++ b/src/Umbraco.Core/Persistence/RepositoryFactory.cs @@ -32,12 +32,26 @@ namespace Umbraco.Core.Persistence if (settings == null) throw new ArgumentNullException("settings"); _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) { - _cacheHelper = new CacheHelper(new DeepCloneRuntimeCacheProvider(_cacheHelper.RuntimeCache), _cacheHelper.StaticCache, _cacheHelper.RequestCache); + 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; + })); } _noCache = CacheHelper.CreateDisabledCacheHelper(); @@ -140,7 +154,6 @@ namespace Umbraco.Core.Persistence { return new DataTypeDefinitionRepository( uow, - _cacheHelper, _cacheHelper, _logger, _sqlSyntax, CreateContentTypeRepository(uow)); @@ -295,8 +308,7 @@ namespace Umbraco.Core.Persistence { return new MemberGroupRepository(uow, _cacheHelper, - _logger, _sqlSyntax, - _cacheHelper); + _logger, _sqlSyntax); } public virtual IEntityRepository CreateEntityRepository(IDatabaseUnitOfWork uow) diff --git a/src/Umbraco.Core/Services/ApplicationTreeService.cs b/src/Umbraco.Core/Services/ApplicationTreeService.cs index f640fa8d22..c9ce839450 100644 --- a/src/Umbraco.Core/Services/ApplicationTreeService.cs +++ b/src/Umbraco.Core/Services/ApplicationTreeService.cs @@ -315,7 +315,7 @@ namespace Umbraco.Core.Services //remove the cache now that it has changed SD: I'm leaving this here even though it // is taken care of by events as well, I think unit tests may rely on it being cleared here. - _cache.ClearCacheItem(CacheKeys.ApplicationTreeCacheKey); + _cache.RuntimeCache.ClearCacheItem(CacheKeys.ApplicationTreeCacheKey); } } } diff --git a/src/Umbraco.Core/Services/SectionService.cs b/src/Umbraco.Core/Services/SectionService.cs index cc25387a00..b810840873 100644 --- a/src/Umbraco.Core/Services/SectionService.cs +++ b/src/Umbraco.Core/Services/SectionService.cs @@ -171,7 +171,7 @@ namespace Umbraco.Core.Services //remove the cache so it gets re-read ... SD: I'm leaving this here even though it // is taken care of by events as well, I think unit tests may rely on it being cleared here. - _cache.ClearCacheItem(CacheKeys.ApplicationsCacheKey); + _cache.RuntimeCache.ClearCacheItem(CacheKeys.ApplicationsCacheKey); } } } diff --git a/src/Umbraco.Core/Services/ServiceContext.cs b/src/Umbraco.Core/Services/ServiceContext.cs index f8a78aed3d..9d0da8aca2 100644 --- a/src/Umbraco.Core/Services/ServiceContext.cs +++ b/src/Umbraco.Core/Services/ServiceContext.cs @@ -286,6 +286,7 @@ namespace Umbraco.Core.Services _entityService = new Lazy(() => new EntityService( provider, repositoryFactory, logger, eventMessagesFactory, _contentService.Value, _contentTypeService.Value, _mediaService.Value, _dataTypeService.Value, _memberService.Value, _memberTypeService.Value, + //TODO: Consider making this an isolated cache instead of using the global one cache.RuntimeCache)); if (_relationService == null) diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index d294bdaddf..dd83553074 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -162,6 +162,7 @@ + diff --git a/src/Umbraco.Tests/Macros/MacroTests.cs b/src/Umbraco.Tests/Macros/MacroTests.cs index 4f0b91d4ca..23c1c7f1f1 100644 --- a/src/Umbraco.Tests/Macros/MacroTests.cs +++ b/src/Umbraco.Tests/Macros/MacroTests.cs @@ -27,7 +27,8 @@ namespace Umbraco.Tests.Macros var cacheHelper = new CacheHelper( new ObjectCacheRuntimeCacheProvider(), new StaticCacheProvider(), - new NullCacheProvider()); + new NullCacheProvider(), + new IsolatedRuntimeCache(type => new ObjectCacheRuntimeCacheProvider())); ApplicationContext.Current = new ApplicationContext(cacheHelper, new ProfilingLogger(Mock.Of(), Mock.Of())); UmbracoConfig.For.SetUmbracoSettings(SettingsForTests.GetDefault()); @@ -36,7 +37,7 @@ namespace Umbraco.Tests.Macros [TearDown] public void TearDown() { - ApplicationContext.Current.ApplicationCache.ClearAllCache(); + ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearAllCache(); ApplicationContext.Current.DisposeIfDisposable(); ApplicationContext.Current = null; } @@ -136,11 +137,11 @@ namespace Umbraco.Tests.Macros public void Macro_Needs_Removing_Based_On_Macro_File(int minutesToNow, bool expectedResult) { var now = DateTime.Now; - ApplicationContext.Current.ApplicationCache.InsertCacheItem( + ApplicationContext.Current.ApplicationCache.RuntimeCache.InsertCacheItem( "TestDate", - CacheItemPriority.NotRemovable, - new TimeSpan(0, 0, 60), - () => now.AddMinutes(minutesToNow)); //add a datetime value of 'now' with the minutes offset + priority: CacheItemPriority.NotRemovable, + timeout: new TimeSpan(0, 0, 60), + getCacheItem: () => now.AddMinutes(minutesToNow)); //add a datetime value of 'now' with the minutes offset //now we need to update a file's date to 'now' to compare var path = Path.Combine(TestHelpers.TestHelper.CurrentAssemblyDirectory, "temp.txt"); diff --git a/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs index 289bd628ee..f20de479a7 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs @@ -34,7 +34,6 @@ namespace Umbraco.Tests.Persistence.Repositories { var dataTypeDefinitionRepository = new DataTypeDefinitionRepository( unitOfWork, CacheHelper.CreateDisabledCacheHelper(), - CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, new ContentTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, new TemplateRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, Mock.Of(), Mock.Of(), Mock.Of()))); @@ -376,10 +375,14 @@ namespace Umbraco.Tests.Persistence.Repositories var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); - var cache = new CacheHelper(new ObjectCacheRuntimeCacheProvider(), new StaticCacheProvider(), new StaticCacheProvider()); + var cache = new CacheHelper( + new ObjectCacheRuntimeCacheProvider(), + new StaticCacheProvider(), + new StaticCacheProvider(), + new IsolatedRuntimeCache(type => new ObjectCacheRuntimeCacheProvider())); Func creator = () => new DataTypeDefinitionRepository( - unitOfWork, CacheHelper.CreateDisabledCacheHelper(), + unitOfWork, cache, Mock.Of(), SqlSyntax, new ContentTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, @@ -402,7 +405,8 @@ namespace Umbraco.Tests.Persistence.Repositories var collection = repository.GetPreValuesCollectionByDataTypeId(dtd.Id); } - var cached = cache.RuntimeCache.GetCacheItemsByKeySearch(CacheKeys.DataTypePreValuesCacheKey + dtd.Id + "-"); + var cached = cache.IsolatedRuntimeCache.GetCache().Result + .GetCacheItemsByKeySearch(CacheKeys.DataTypePreValuesCacheKey + dtd.Id + "-"); Assert.IsNotNull(cached); Assert.AreEqual(1, cached.Count()); @@ -415,10 +419,14 @@ namespace Umbraco.Tests.Persistence.Repositories var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); - var cache = new CacheHelper(new ObjectCacheRuntimeCacheProvider(), new StaticCacheProvider(), new StaticCacheProvider()); + var cache = new CacheHelper( + new ObjectCacheRuntimeCacheProvider(), + new StaticCacheProvider(), + new StaticCacheProvider(), + new IsolatedRuntimeCache(type => new ObjectCacheRuntimeCacheProvider())); Func creator = () => new DataTypeDefinitionRepository( - unitOfWork, CacheHelper.CreateDisabledCacheHelper(), + unitOfWork, cache, Mock.Of(), SqlSyntax, new ContentTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, @@ -441,7 +449,8 @@ namespace Umbraco.Tests.Persistence.Repositories var val = repository.GetPreValueAsString(Convert.ToInt32(id)); } - var cached = cache.RuntimeCache.GetCacheItemsByKeySearch(CacheKeys.DataTypePreValuesCacheKey + dtd.Id + "-"); + var cached = cache.IsolatedRuntimeCache.GetCache().Result + .GetCacheItemsByKeySearch(CacheKeys.DataTypePreValuesCacheKey + dtd.Id + "-"); Assert.IsNotNull(cached); Assert.AreEqual(1, cached.Count()); diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs index 64e8587e00..0d3b4e4e47 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs @@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Repositories private MemberRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out MemberTypeRepository memberTypeRepository, out MemberGroupRepository memberGroupRepository) { memberTypeRepository = new MemberTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax); - memberGroupRepository = new MemberGroupRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, CacheHelper.CreateDisabledCacheHelper()); + memberGroupRepository = new MemberGroupRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax); var tagRepo = new TagRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax); var repository = new MemberRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, memberTypeRepository, memberGroupRepository, tagRepo, Mock.Of()); return repository; diff --git a/src/Umbraco.Web/Cache/ApplicationCacheRefresher.cs b/src/Umbraco.Web/Cache/ApplicationCacheRefresher.cs index 8b742b1b2c..5c1ec9e1d4 100644 --- a/src/Umbraco.Web/Cache/ApplicationCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/ApplicationCacheRefresher.cs @@ -26,7 +26,7 @@ namespace Umbraco.Web.Cache public override void RefreshAll() { - ApplicationContext.Current.ApplicationCache.ClearCacheItem(CacheKeys.ApplicationsCacheKey); + ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(CacheKeys.ApplicationsCacheKey); base.RefreshAll(); } @@ -38,7 +38,7 @@ namespace Umbraco.Web.Cache public override void Remove(int id) { - ApplicationContext.Current.ApplicationCache.ClearCacheItem(CacheKeys.ApplicationsCacheKey); + ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(CacheKeys.ApplicationsCacheKey); base.Remove(id); } diff --git a/src/Umbraco.Web/Cache/ApplicationTreeCacheRefresher.cs b/src/Umbraco.Web/Cache/ApplicationTreeCacheRefresher.cs index e267b441a2..2f1ab4b891 100644 --- a/src/Umbraco.Web/Cache/ApplicationTreeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/ApplicationTreeCacheRefresher.cs @@ -26,7 +26,7 @@ namespace Umbraco.Web.Cache public override void RefreshAll() { - ApplicationContext.Current.ApplicationCache.ClearCacheItem(CacheKeys.ApplicationTreeCacheKey); + ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(CacheKeys.ApplicationTreeCacheKey); base.RefreshAll(); } @@ -38,7 +38,7 @@ namespace Umbraco.Web.Cache public override void Remove(int id) { - ApplicationContext.Current.ApplicationCache.ClearCacheItem(CacheKeys.ApplicationTreeCacheKey); + ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(CacheKeys.ApplicationTreeCacheKey); base.Remove(id); } diff --git a/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs index 502e215c90..03b7e0ee59 100644 --- a/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs @@ -126,9 +126,9 @@ namespace Umbraco.Web.Cache public override void RefreshAll() { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); - + ClearAllCacheByRepositoryEntityType(); + ClearAllCacheByRepositoryEntityType(); + //all property type cache ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch(CacheKeys.PropertyTypeCacheKey); //all content type property cache @@ -179,7 +179,7 @@ namespace Umbraco.Web.Cache /// - InMemoryCacheProvider.Current.Clear(); /// - RoutesCache.Clear(); /// - private static void ClearContentTypeCache(JsonPayload[] payloads) + private void ClearContentTypeCache(JsonPayload[] payloads) { var needsContentRefresh = false; @@ -214,18 +214,18 @@ namespace Umbraco.Web.Cache { if (payloads.Any(x => x.Type == typeof (IContentType).Name)) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); + ClearAllCacheByRepositoryEntityType(); } if (payloads.Any(x => x.Type == typeof(IMediaType).Name)) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); + ClearAllCacheByRepositoryEntityType(); } if (payloads.Any(x => x.Type == typeof(IMemberType).Name)) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); + ClearAllCacheByRepositoryEntityType(); } @@ -291,7 +291,7 @@ namespace Umbraco.Web.Cache /// /// true if the entity was deleted, false if it is just an update /// - private static void ClearContentTypeCache(bool isDeleted, params int[] ids) + private void ClearContentTypeCache(bool isDeleted, params int[] ids) { ClearContentTypeCache( ids.Select( diff --git a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs index 86114d5f77..6a813df2fd 100644 --- a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs @@ -92,27 +92,22 @@ namespace Umbraco.Web.Cache // db data type to store the value against and anytime a datatype changes, this also might change // we basically need to clear all sorts of runtime caches here because so many things depend upon a data type - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); + ClearAllCacheByRepositoryEntityType(); + ClearAllCacheByRepositoryEntityType(); + ClearAllCacheByRepositoryEntityType(); + ClearAllCacheByRepositoryEntityType(); + ClearAllCacheByRepositoryEntityType(); ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch(CacheKeys.IdToKeyCacheKey); ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch(CacheKeys.KeyToIdCacheKey); payloads.ForEach(payload => { - //clear both the Id and Unique Id cache since we cache both in the legacy classes :( - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch( - string.Format("{0}{1}", CacheKeys.DataTypeCacheKey, payload.Id)); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch( - string.Format("{0}{1}", CacheKeys.DataTypeCacheKey, payload.UniqueId)); - //clears the prevalue cache - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch( - string.Format("{0}{1}", CacheKeys.DataTypePreValuesCacheKey, payload.Id)); - + var dataTypeCache = ApplicationContext.Current.ApplicationCache.IsolatedRuntimeCache.GetCache(); + if (dataTypeCache) + dataTypeCache.Result.ClearCacheByKeySearch(string.Format("{0}{1}", CacheKeys.DataTypePreValuesCacheKey, payload.Id)); + PublishedContentType.ClearDataType(payload.Id); }); diff --git a/src/Umbraco.Web/Cache/DictionaryCacheRefresher.cs b/src/Umbraco.Web/Cache/DictionaryCacheRefresher.cs index 8209d247a2..6dff68544a 100644 --- a/src/Umbraco.Web/Cache/DictionaryCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/DictionaryCacheRefresher.cs @@ -28,13 +28,13 @@ namespace Umbraco.Web.Cache public override void Refresh(int id) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); base.Refresh(id); } public override void Remove(int id) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); base.Remove(id); } } diff --git a/src/Umbraco.Web/Cache/DistributedCache.cs b/src/Umbraco.Web/Cache/DistributedCache.cs index 27c30d89e8..6848ce2496 100644 --- a/src/Umbraco.Web/Cache/DistributedCache.cs +++ b/src/Umbraco.Web/Cache/DistributedCache.cs @@ -38,6 +38,9 @@ namespace Umbraco.Web.Cache public const string ContentTypeCacheRefresherId = "6902E22C-9C10-483C-91F3-66B7CAE9E2F5"; public const string LanguageCacheRefresherId = "3E0F95D8-0BE5-44B8-8394-2B8750B62654"; public const string DomainCacheRefresherId = "11290A79-4B57-4C99-AD72-7748A3CF38AF"; + + [Obsolete("This is no longer used and will be removed in future versions")] + [EditorBrowsable(EditorBrowsableState.Never)] public const string StylesheetCacheRefresherId = "E0633648-0DEB-44AE-9A48-75C3A55CB670"; public const string StylesheetPropertyCacheRefresherId = "2BC7A3A4-6EB1-4FBC-BAA3-C9E7B6D36D38"; public const string DataTypeCacheRefresherId = "35B16C25-A17E-45D7-BC8F-EDAB1DCC28D2"; diff --git a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs index 66cb82ff7c..750872d8af 100644 --- a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs +++ b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs @@ -442,7 +442,7 @@ namespace Umbraco.Web.Cache public static void ClearXsltCacheOnCurrentServer(this DistributedCache dc) { if (UmbracoConfig.For.UmbracoSettings().Content.UmbracoLibraryCacheDuration <= 0) return; - ApplicationContext.Current.ApplicationCache.ClearCacheObjectTypes("MS.Internal.Xml.XPath.XPathSelectionIterator"); + ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes("MS.Internal.Xml.XPath.XPathSelectionIterator"); } #endregion diff --git a/src/Umbraco.Web/Cache/DomainCacheRefresher.cs b/src/Umbraco.Web/Cache/DomainCacheRefresher.cs index 51a2c79b2d..e5b1d9365d 100644 --- a/src/Umbraco.Web/Cache/DomainCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/DomainCacheRefresher.cs @@ -41,8 +41,8 @@ namespace Umbraco.Web.Cache } private void ClearCache() - { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + { + ClearAllCacheByRepositoryEntityType(); // SD: we need to clear the routes cache here! // diff --git a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs index 019be66b15..13edcb3b68 100644 --- a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs @@ -28,13 +28,13 @@ namespace Umbraco.Web.Cache public override void Refresh(int id) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); base.Refresh(id); } public override void Remove(int id) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); base.Remove(id); } } diff --git a/src/Umbraco.Web/Cache/MacroCacheRefresher.cs b/src/Umbraco.Web/Cache/MacroCacheRefresher.cs index a06501032f..6dd8aa9805 100644 --- a/src/Umbraco.Web/Cache/MacroCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/MacroCacheRefresher.cs @@ -176,7 +176,7 @@ namespace Umbraco.Web.Cache prefix => ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch(prefix)); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); base.RefreshAll(); } @@ -191,7 +191,11 @@ namespace Umbraco.Web.Cache alias => ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch(alias)); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(RepositoryBase.GetCacheIdKey(payload.Id)); + var macroRepoCache = ApplicationContext.Current.ApplicationCache.IsolatedRuntimeCache.GetCache(); + if (macroRepoCache) + { + macroRepoCache.Result.ClearCacheItem(RepositoryBase.GetCacheIdKey(payload.Id)); + } }); base.Refresh(jsonPayload); diff --git a/src/Umbraco.Web/Cache/MediaCacheRefresher.cs b/src/Umbraco.Web/Cache/MediaCacheRefresher.cs index dce512b1dc..a0e037e110 100644 --- a/src/Umbraco.Web/Cache/MediaCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/MediaCacheRefresher.cs @@ -24,7 +24,7 @@ namespace Umbraco.Web.Cache public class MediaCacheRefresher : JsonCacheRefresherBase { #region Static helpers - + /// /// Converts the json to a JsonPayload object /// @@ -143,13 +143,13 @@ namespace Umbraco.Web.Cache } public override void Remove(int id) - { + { ClearCache(FromMedia(ApplicationContext.Current.Services.MediaService.GetById(id), //NOTE: we'll just default to trashed for this one. OperationType.Trashed)); base.Remove(id); } - + private static void ClearCache(params JsonPayload[] payloads) { if (payloads == null) return; @@ -159,40 +159,40 @@ namespace Umbraco.Web.Cache ApplicationContext.Current.ApplicationCache.ClearPartialViewCache(); payloads.ForEach(payload => + { + var mediaCache = ApplicationContext.Current.ApplicationCache.IsolatedRuntimeCache.GetCache(); + + //if there's no path, then just use id (this will occur on permanent deletion like emptying recycle bin) + if (payload.Path.IsNullOrWhiteSpace()) { - - //if there's no path, then just use id (this will occur on permanent deletion like emptying recycle bin) - if (payload.Path.IsNullOrWhiteSpace()) + ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch( + string.Format("{0}_{1}", CacheKeys.MediaCacheKey, payload.Id)); + } + else + { + foreach (var idPart in payload.Path.Split(',')) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch( - string.Format("{0}_{1}", CacheKeys.MediaCacheKey, payload.Id)); - } - else - { - foreach (var idPart in payload.Path.Split(',')) + int idPartAsInt; + if (int.TryParse(idPart, out idPartAsInt) && mediaCache) { - int idPartAsInt; - if (int.TryParse(idPart, out idPartAsInt)) - { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem( - RepositoryBase.GetCacheIdKey(idPartAsInt)); - } + mediaCache.Result.ClearCacheItem(RepositoryBase.GetCacheIdKey(idPartAsInt)); + } + ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch( + string.Format("{0}_{1}_True", CacheKeys.MediaCacheKey, idPart)); + + // Also clear calls that only query this specific item! + if (idPart == payload.Id.ToString(CultureInfo.InvariantCulture)) ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch( - string.Format("{0}_{1}_True", CacheKeys.MediaCacheKey, idPart)); - - // Also clear calls that only query this specific item! - if (idPart == payload.Id.ToString(CultureInfo.InvariantCulture)) - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch( - string.Format("{0}_{1}", CacheKeys.MediaCacheKey, payload.Id)); - } + string.Format("{0}_{1}", CacheKeys.MediaCacheKey, payload.Id)); } + } + + // published cache... + PublishedMediaCache.ClearCache(payload.Id); + }); - // published cache... - PublishedMediaCache.ClearCache(payload.Id); - }); - } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Cache/MemberCacheRefresher.cs b/src/Umbraco.Web/Cache/MemberCacheRefresher.cs index a0167454a5..32e6a69717 100644 --- a/src/Umbraco.Web/Cache/MemberCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/MemberCacheRefresher.cs @@ -69,7 +69,9 @@ namespace Umbraco.Web.Cache ApplicationContext.Current.ApplicationCache.RuntimeCache. ClearCacheByKeySearch(string.Format("{0}{1}", CacheKeys.MemberBusinessLogicCacheKey, id)); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(RepositoryBase.GetCacheIdKey(id)); + var memberCache = ApplicationContext.Current.ApplicationCache.IsolatedRuntimeCache.GetCache(); + if (memberCache) + memberCache.Result.ClearCacheItem(RepositoryBase.GetCacheIdKey(id)); } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Cache/MemberGroupCacheRefresher.cs b/src/Umbraco.Web/Cache/MemberGroupCacheRefresher.cs index e410ab560c..dc2ba39b9d 100644 --- a/src/Umbraco.Web/Cache/MemberGroupCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/MemberGroupCacheRefresher.cs @@ -104,13 +104,13 @@ namespace Umbraco.Web.Cache { if (payloads == null) return; + var memberGroupCache = ApplicationContext.Current.ApplicationCache.IsolatedRuntimeCache.GetCache(); payloads.ForEach(payload => { - if (payload != null) + if (payload != null && memberGroupCache) { - ApplicationContext.Current.ApplicationCache.RuntimeCache - .ClearCacheByKeySearch(string.Format("{0}.{1}", typeof(IMemberGroup).FullName, payload.Name)); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(RepositoryBase.GetCacheIdKey(payload.Id)); + memberGroupCache.Result.ClearCacheByKeySearch(string.Format("{0}.{1}", typeof(IMemberGroup).FullName, payload.Name)); + memberGroupCache.Result.ClearCacheItem(RepositoryBase.GetCacheIdKey(payload.Id)); } }); diff --git a/src/Umbraco.Web/Cache/PageCacheRefresher.cs b/src/Umbraco.Web/Cache/PageCacheRefresher.cs index 73f525383e..8461f57d64 100644 --- a/src/Umbraco.Web/Cache/PageCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/PageCacheRefresher.cs @@ -76,7 +76,7 @@ namespace Umbraco.Web.Cache content.Instance.ClearDocumentCache(id); DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer(); DistributedCache.Instance.ClearXsltCacheOnCurrentServer(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); base.Remove(id); } @@ -86,7 +86,7 @@ namespace Umbraco.Web.Cache content.Instance.UpdateDocumentCache(new Document(instance)); DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer(); DistributedCache.Instance.ClearXsltCacheOnCurrentServer(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); base.Refresh(instance); } @@ -96,7 +96,7 @@ namespace Umbraco.Web.Cache content.Instance.ClearDocumentCache(new Document(instance)); DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer(); DistributedCache.Instance.ClearXsltCacheOnCurrentServer(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); base.Remove(instance); } } diff --git a/src/Umbraco.Web/Cache/PublicAccessCacheRefresher.cs b/src/Umbraco.Web/Cache/PublicAccessCacheRefresher.cs index 09b38f1ac3..77d7314941 100644 --- a/src/Umbraco.Web/Cache/PublicAccessCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/PublicAccessCacheRefresher.cs @@ -27,25 +27,25 @@ namespace Umbraco.Web.Cache public override void Refresh(Guid id) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); base.Refresh(id); } public override void Refresh(int id) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); base.Refresh(id); } public override void RefreshAll() { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); base.RefreshAll(); } public override void Remove(int id) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); base.Remove(id); } } diff --git a/src/Umbraco.Web/Cache/StylesheetCacheRefresher.cs b/src/Umbraco.Web/Cache/StylesheetCacheRefresher.cs index 5d98671a76..959a937e7b 100644 --- a/src/Umbraco.Web/Cache/StylesheetCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/StylesheetCacheRefresher.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel; using Umbraco.Core; using Umbraco.Core.Cache; @@ -7,6 +8,8 @@ namespace Umbraco.Web.Cache /// /// A cache refresher to ensure stylesheet cache is refreshed when stylesheets change /// + [Obsolete("This is no longer used and will be removed in future versions")] + [EditorBrowsable(EditorBrowsableState.Never)] public sealed class StylesheetCacheRefresher : CacheRefresherBase { protected override StylesheetCacheRefresher Instance @@ -24,27 +27,5 @@ namespace Umbraco.Web.Cache get { return "Stylesheet cache refresher"; } } - public override void RefreshAll() - { - ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(CacheKeys.StylesheetCacheKey); - base.RefreshAll(); - } - - public override void Refresh(int id) - { - ApplicationContext.Current.ApplicationCache.ClearCacheItem(GetStylesheetCacheKey(id)); - base.Refresh(id); - } - - public override void Remove(int id) - { - ApplicationContext.Current.ApplicationCache.ClearCacheItem(GetStylesheetCacheKey(id)); - base.Remove(id); - } - - private static string GetStylesheetCacheKey(int id) - { - return CacheKeys.StylesheetCacheKey + id; - } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Cache/StylesheetPropertyCacheRefresher.cs b/src/Umbraco.Web/Cache/StylesheetPropertyCacheRefresher.cs index d7006c8531..5b72e0384b 100644 --- a/src/Umbraco.Web/Cache/StylesheetPropertyCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/StylesheetPropertyCacheRefresher.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel; using Umbraco.Core; using Umbraco.Core.Cache; @@ -7,6 +8,8 @@ namespace Umbraco.Web.Cache /// /// A cache refresher to ensure stylesheet property cache is refreshed when stylesheet properties change /// + [Obsolete("This is no longer used and will be removed in future versions")] + [EditorBrowsable(EditorBrowsableState.Never)] public sealed class StylesheetPropertyCacheRefresher : CacheRefresherBase { protected override StylesheetPropertyCacheRefresher Instance @@ -23,28 +26,6 @@ namespace Umbraco.Web.Cache { get { return "Stylesheet property cache refresher"; } } - - public override void RefreshAll() - { - ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(CacheKeys.StylesheetPropertyCacheKey); - base.RefreshAll(); - } - - public override void Refresh(int id) - { - ApplicationContext.Current.ApplicationCache.ClearCacheItem(GetStylesheetPropertyCacheKey(id)); - base.Refresh(id); - } - - public override void Remove(int id) - { - ApplicationContext.Current.ApplicationCache.ClearCacheItem(GetStylesheetPropertyCacheKey(id)); - base.Remove(id); - } - - private static string GetStylesheetPropertyCacheKey(int id) - { - return CacheKeys.StylesheetPropertyCacheKey + id; - } + } } \ No newline at end of file diff --git a/src/Umbraco.Web/Cache/TemplateCacheRefresher.cs b/src/Umbraco.Web/Cache/TemplateCacheRefresher.cs index 22bce3d5bf..12988e921c 100644 --- a/src/Umbraco.Web/Cache/TemplateCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/TemplateCacheRefresher.cs @@ -52,8 +52,8 @@ namespace Umbraco.Web.Cache // all three of these types are referenced by templates, and the cache needs to be cleared on every server, // otherwise things like looking up content type's after a template is removed is still going to show that // it has an associated template. - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); + ClearAllCacheByRepositoryEntityType(); base.Remove(id); } @@ -66,7 +66,7 @@ namespace Umbraco.Web.Cache string.Format("{0}{1}", CacheKeys.TemplateFrontEndCacheKey, id)); //need to clear the runtime cache for templates - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); } } diff --git a/src/Umbraco.Web/Cache/UnpublishedPageCacheRefresher.cs b/src/Umbraco.Web/Cache/UnpublishedPageCacheRefresher.cs index e3601188f4..d4efcb96c7 100644 --- a/src/Umbraco.Web/Cache/UnpublishedPageCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/UnpublishedPageCacheRefresher.cs @@ -77,16 +77,16 @@ namespace Umbraco.Web.Cache public override void RefreshAll() { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); + ClearAllCacheByRepositoryEntityType(); DistributedCache.Instance.ClearDomainCacheOnCurrentServer(); base.RefreshAll(); } public override void Refresh(int id) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(RepositoryBase.GetCacheIdKey(id)); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearRepositoryCacheItemById(id); + ClearAllCacheByRepositoryEntityType(); content.Instance.UpdateSortOrder(id); DistributedCache.Instance.ClearDomainCacheOnCurrentServer(); base.Refresh(id); @@ -94,8 +94,8 @@ namespace Umbraco.Web.Cache public override void Remove(int id) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(RepositoryBase.GetCacheIdKey(id)); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearRepositoryCacheItemById(id); + ClearAllCacheByRepositoryEntityType(); DistributedCache.Instance.ClearDomainCacheOnCurrentServer(); base.Remove(id); } @@ -103,8 +103,8 @@ namespace Umbraco.Web.Cache public override void Refresh(IContent instance) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(RepositoryBase.GetCacheIdKey(instance.Id)); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearRepositoryCacheItemById(instance.Id); + ClearAllCacheByRepositoryEntityType(); content.Instance.UpdateSortOrder(instance); DistributedCache.Instance.ClearDomainCacheOnCurrentServer(); base.Refresh(instance); @@ -112,8 +112,8 @@ namespace Umbraco.Web.Cache public override void Remove(IContent instance) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(RepositoryBase.GetCacheIdKey(instance.Id)); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearRepositoryCacheItemById(instance.Id); + ClearAllCacheByRepositoryEntityType(); DistributedCache.Instance.ClearDomainCacheOnCurrentServer(); base.Remove(instance); } @@ -124,11 +124,11 @@ namespace Umbraco.Web.Cache /// public void Refresh(string jsonPayload) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); foreach (var payload in DeserializeFromJsonPayload(jsonPayload)) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(RepositoryBase.GetCacheIdKey(payload.Id)); + ClearRepositoryCacheItemById(payload.Id); content.Instance.UpdateSortOrder(payload.Id); } @@ -136,6 +136,15 @@ namespace Umbraco.Web.Cache OnCacheUpdated(Instance, new CacheRefresherEventArgs(jsonPayload, MessageType.RefreshByJson)); } + + private void ClearRepositoryCacheItemById(int id) + { + var contentCache = ApplicationContext.Current.ApplicationCache.IsolatedRuntimeCache.GetCache(); + if (contentCache) + { + contentCache.Result.ClearCacheItem(RepositoryBase.GetCacheIdKey(id)); + } + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Cache/UserCacheRefresher.cs b/src/Umbraco.Web/Cache/UserCacheRefresher.cs index 95a7fdac49..7efbef5f9a 100644 --- a/src/Umbraco.Web/Cache/UserCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/UserCacheRefresher.cs @@ -30,9 +30,9 @@ namespace Umbraco.Web.Cache public override void RefreshAll() { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch(CacheKeys.UserPermissionsCacheKey); - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch(CacheKeys.UserContextCacheKey); + ClearAllCacheByRepositoryEntityType(); + if (UserPermissionsCache) + UserPermissionsCache.Result.ClearCacheByKeySearch(CacheKeys.UserPermissionsCacheKey); base.RefreshAll(); } @@ -44,16 +44,20 @@ namespace Umbraco.Web.Cache public override void Remove(int id) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(RepositoryBase.GetCacheIdKey(id)); - - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(string.Format("{0}{1}", CacheKeys.UserPermissionsCacheKey, id)); - - //we need to clear all UserContextCacheKey since we cannot invalidate based on ID since the cache is done so based - //on the current contextId stored in the database - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch(CacheKeys.UserContextCacheKey); + var userCache = ApplicationContext.Current.ApplicationCache.IsolatedRuntimeCache.GetCache(); + if (userCache) + userCache.Result.ClearCacheItem(RepositoryBase.GetCacheIdKey(id)); + if (UserPermissionsCache) + UserPermissionsCache.Result.ClearCacheItem(string.Format("{0}{1}", CacheKeys.UserPermissionsCacheKey, id)); + base.Remove(id); } + private Attempt UserPermissionsCache + { + get { return ApplicationContext.Current.ApplicationCache.IsolatedRuntimeCache.GetCache(); } + } + } } \ No newline at end of file diff --git a/src/Umbraco.Web/Cache/UserPermissionsCacheRefresher.cs b/src/Umbraco.Web/Cache/UserPermissionsCacheRefresher.cs index db1baf1bcd..64744024ed 100644 --- a/src/Umbraco.Web/Cache/UserPermissionsCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/UserPermissionsCacheRefresher.cs @@ -1,6 +1,7 @@ using System; using Umbraco.Core; using Umbraco.Core.Cache; +using Umbraco.Core.Models.Membership; namespace Umbraco.Web.Cache { @@ -31,7 +32,8 @@ namespace Umbraco.Web.Cache public override void RefreshAll() { - ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(CacheKeys.UserPermissionsCacheKey); + if (UserPermissionsCache) + UserPermissionsCache.Result.ClearCacheByKeySearch(CacheKeys.UserPermissionsCacheKey); base.RefreshAll(); } @@ -43,8 +45,14 @@ namespace Umbraco.Web.Cache public override void Remove(int id) { - ApplicationContext.Current.ApplicationCache.ClearCacheItem(string.Format("{0}{1}", CacheKeys.UserPermissionsCacheKey, id)); + if (UserPermissionsCache) + UserPermissionsCache.Result.ClearCacheItem(string.Format("{0}{1}", CacheKeys.UserPermissionsCacheKey, id)); base.Remove(id); } + + private Attempt UserPermissionsCache + { + get { return ApplicationContext.Current.ApplicationCache.IsolatedRuntimeCache.GetCache(); } + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Cache/UserTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/UserTypeCacheRefresher.cs index 2beaa4347d..d67865a188 100644 --- a/src/Umbraco.Web/Cache/UserTypeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/UserTypeCacheRefresher.cs @@ -29,19 +29,23 @@ namespace Umbraco.Web.Cache public override void RefreshAll() { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheObjectTypes(); + ClearAllCacheByRepositoryEntityType(); base.RefreshAll(); } public override void Refresh(int id) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(RepositoryBase.GetCacheIdKey(id)); + var userTypeCache = ApplicationContext.Current.ApplicationCache.IsolatedRuntimeCache.GetCache(); + if (userTypeCache) + userTypeCache.Result.ClearCacheItem(RepositoryBase.GetCacheIdKey(id)); base.Refresh(id); } public override void Remove(int id) { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem(RepositoryBase.GetCacheIdKey(id)); + var userTypeCache = ApplicationContext.Current.ApplicationCache.IsolatedRuntimeCache.GetCache(); + if (userTypeCache) + userTypeCache.Result.ClearCacheItem(RepositoryBase.GetCacheIdKey(id)); base.Remove(id); } diff --git a/src/Umbraco.Web/CacheHelperExtensions.cs b/src/Umbraco.Web/CacheHelperExtensions.cs index f23bb6d070..1b0451a999 100644 --- a/src/Umbraco.Web/CacheHelperExtensions.cs +++ b/src/Umbraco.Web/CacheHelperExtensions.cs @@ -58,7 +58,7 @@ namespace Umbraco.Web /// public static void ClearPartialViewCache(this CacheHelper cacheHelper) { - cacheHelper.ClearCacheByKeySearch(PartialViewCacheKey); + cacheHelper.RuntimeCache.ClearCacheByKeySearch(PartialViewCacheKey); } } } diff --git a/src/Umbraco.Web/Media/ImageUrl.cs b/src/Umbraco.Web/Media/ImageUrl.cs index 8f56d8bfa4..dff9358a38 100644 --- a/src/Umbraco.Web/Media/ImageUrl.cs +++ b/src/Umbraco.Web/Media/ImageUrl.cs @@ -87,7 +87,7 @@ namespace Umbraco.Web.Media private static object GetContentFromCache(int nodeIdInt, string field) { - var content = ApplicationContext.Current.ApplicationCache.GetCacheItem( + var content = ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem( string.Format("{0}{1}_{2}", CacheKeys.ContentItemCacheKey, nodeIdInt.ToString(CultureInfo.InvariantCulture), field)); return content; } diff --git a/src/Umbraco.Web/umbraco.presentation/content.cs b/src/Umbraco.Web/umbraco.presentation/content.cs index 23e44896f4..0bee9e631a 100644 --- a/src/Umbraco.Web/umbraco.presentation/content.cs +++ b/src/Umbraco.Web/umbraco.presentation/content.cs @@ -297,7 +297,7 @@ namespace umbraco ClearContextCache(); var cachedFieldKeyStart = string.Format("{0}{1}_", CacheKeys.ContentItemCacheKey, d.Id); - ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(cachedFieldKeyStart); + ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch(cachedFieldKeyStart); FireAfterUpdateDocumentCache(d, e); } diff --git a/src/Umbraco.Web/umbraco.presentation/library.cs b/src/Umbraco.Web/umbraco.presentation/library.cs index cbfdafc56a..d9b1d520ed 100644 --- a/src/Umbraco.Web/umbraco.presentation/library.cs +++ b/src/Umbraco.Web/umbraco.presentation/library.cs @@ -493,11 +493,11 @@ namespace umbraco { if (UmbracoConfig.For.UmbracoSettings().Content.UmbracoLibraryCacheDuration > 0) { - var xml = ApplicationContext.Current.ApplicationCache.GetCacheItem( + var xml = ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem( string.Format( "{0}_{1}_{2}", CacheKeys.MediaCacheKey, MediaId, Deep), - TimeSpan.FromSeconds(UmbracoConfig.For.UmbracoSettings().Content.UmbracoLibraryCacheDuration), - () => GetMediaDo(MediaId, Deep)); + timeout: TimeSpan.FromSeconds(UmbracoConfig.For.UmbracoSettings().Content.UmbracoLibraryCacheDuration), + getCacheItem: () => GetMediaDo(MediaId, Deep)); if (xml != null) { @@ -552,11 +552,11 @@ namespace umbraco { if (UmbracoConfig.For.UmbracoSettings().Content.UmbracoLibraryCacheDuration > 0) { - var xml = ApplicationContext.Current.ApplicationCache.GetCacheItem( + var xml = ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem( string.Format( "{0}_{1}", CacheKeys.MemberLibraryCacheKey, MemberId), - TimeSpan.FromSeconds(UmbracoConfig.For.UmbracoSettings().Content.UmbracoLibraryCacheDuration), - () => GetMemberDo(MemberId)); + timeout: TimeSpan.FromSeconds(UmbracoConfig.For.UmbracoSettings().Content.UmbracoLibraryCacheDuration), + getCacheItem: () => GetMemberDo(MemberId)); if (xml != null) { diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index e14cef4eb1..66ba6fea15 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -571,11 +571,11 @@ namespace umbraco } //insert the cache string result - ApplicationContext.Current.ApplicationCache.InsertCacheItem( + ApplicationContext.Current.ApplicationCache.RuntimeCache.InsertCacheItem( CacheKeys.MacroHtmlCacheKey + Model.CacheIdentifier, - CacheItemPriority.NotRemovable, - new TimeSpan(0, 0, Model.CacheDuration), - () => outputCacheString); + priority: CacheItemPriority.NotRemovable, + timeout: new TimeSpan(0, 0, Model.CacheDuration), + getCacheItem: () => outputCacheString); dateAddedCacheKey = CacheKeys.MacroHtmlDateAddedCacheKey + Model.CacheIdentifier; @@ -590,11 +590,11 @@ namespace umbraco else { //insert the cache control result - ApplicationContext.Current.ApplicationCache.InsertCacheItem( + ApplicationContext.Current.ApplicationCache.RuntimeCache.InsertCacheItem( CacheKeys.MacroControlCacheKey + Model.CacheIdentifier, - CacheItemPriority.NotRemovable, - new TimeSpan(0, 0, Model.CacheDuration), - () => new MacroCacheContent(macroControl, macroControl.ID)); + priority: CacheItemPriority.NotRemovable, + timeout: new TimeSpan(0, 0, Model.CacheDuration), + getCacheItem: () => new MacroCacheContent(macroControl, macroControl.ID)); dateAddedCacheKey = CacheKeys.MacroControlDateAddedCacheKey + Model.CacheIdentifier; @@ -603,11 +603,11 @@ namespace umbraco } //insert the date inserted (so we can check file modification date) - ApplicationContext.Current.ApplicationCache.InsertCacheItem( + ApplicationContext.Current.ApplicationCache.RuntimeCache.InsertCacheItem( dateAddedCacheKey, - CacheItemPriority.NotRemovable, - new TimeSpan(0, 0, Model.CacheDuration), - () => DateTime.Now); + priority: CacheItemPriority.NotRemovable, + timeout: new TimeSpan(0, 0, Model.CacheDuration), + getCacheItem: () => DateTime.Now); } @@ -640,7 +640,7 @@ namespace umbraco if (CacheMacroAsString(Model)) { - macroHtml = ApplicationContext.Current.ApplicationCache.GetCacheItem( + macroHtml = ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem( CacheKeys.MacroHtmlCacheKey + Model.CacheIdentifier); // FlorisRobbemont: @@ -666,7 +666,7 @@ namespace umbraco } else { - var cacheContent = ApplicationContext.Current.ApplicationCache.GetCacheItem( + var cacheContent = ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem( CacheKeys.MacroControlCacheKey + Model.CacheIdentifier); if (cacheContent != null) @@ -730,7 +730,7 @@ namespace umbraco { if (MacroIsFileBased(model)) { - var cacheResult = ApplicationContext.Current.ApplicationCache.GetCacheItem(dateAddedKey); + var cacheResult = ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem(dateAddedKey); if (cacheResult != null) { @@ -864,7 +864,7 @@ namespace umbraco [Obsolete("This is no longer used in the codebase and will be removed in future versions")] public static void unloadXslt(string XsltFile) { - ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(CacheKeys.MacroXsltCacheKey + XsltFile); + ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch(CacheKeys.MacroXsltCacheKey + XsltFile); } #region LoadMacroXslt diff --git a/src/Umbraco.Web/umbraco.presentation/template.cs b/src/Umbraco.Web/umbraco.presentation/template.cs index 6c1e23a13e..dfdad324e2 100644 --- a/src/Umbraco.Web/umbraco.presentation/template.cs +++ b/src/Umbraco.Web/umbraco.presentation/template.cs @@ -494,7 +494,7 @@ namespace umbraco { var tId = templateID; - var t = ApplicationContext.Current.ApplicationCache.GetCacheItem( + var t = ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem