diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs index 70276ce15b..ad803ec09c 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs @@ -94,45 +94,42 @@ namespace Umbraco.Core.Models.PublishedContent #region Cache - // note - // default cache refresher events will contain the ID of the refreshed / removed IContentType - // and not the alias. Also, we cannot hook into the cache refresher event here, because it belongs - // to Umbraco.Web, so we do it in Umbraco.Web.Models.PublishedContentTypeCaching. - - // fixme - must refactor PublishedContentType cache refresh + // these methods are NOT called anymore + // instead, ContentTypeCacheRefresher and DataTypeCacheRefresher directly handle the ApplicationCache - static readonly ConcurrentDictionary ContentTypes = new ConcurrentDictionary(); - - // internal, called by PublishedContentTypeCaching - internal static void ClearAll() - { - Logging.LogHelper.Debug("Clear all."); - ContentTypes.Clear(); - } + //// internal, called by ContentTypeCacheRefresher + //internal static void ClearAll() + //{ + // Logging.LogHelper.Debug("Clear all."); + // ApplicationContext.Current.ApplicationCache.ClearStaticCacheByKeySearch("PublishedContentType_"); + //} - // internal, called by PublishedContentTypeCaching - internal static void ClearContentType(int id) - { - Logging.LogHelper.Debug("Clear content type w/id {0}.", () => id); + //// internal, called by ContentTypeCacheRefresher + //internal static void ClearContentType(int id) + //{ + // Logging.LogHelper.Debug("Clear content type w/id {0}.", () => id); + // // requires a predicate because the key does not contain the ID + // ApplicationContext.Current.ApplicationCache.ClearStaticCacheObjectTypes( + // (key, value) => value.Id == id); + //} - // see http://blogs.msdn.com/b/pfxteam/archive/2011/04/02/10149222.aspx - // that should be race-cond safe - ContentTypes.RemoveAll(kvp => kvp.Value.Id == id); - } - - // internal, called by PublishedContentTypeCaching - internal static void ClearDataType(int id) - { - Logging.LogHelper.Debug("Clear data type w/id {0}.", () => id); - - // see note in ClearContentType() - ContentTypes.RemoveAll(kvp => kvp.Value.PropertyTypes.Any(x => x.DataTypeId == id)); - } + //// internal, called by DataTypeCacheRefresher + //internal static void ClearDataType(int id) + //{ + // Logging.LogHelper.Debug("Clear data type w/id {0}.", () => id); + // ApplicationContext.Current.ApplicationCache.ClearStaticCacheObjectTypes( + // (key, value) => value.PropertyTypes.Any(x => x.DataTypeId == id)); + //} public static PublishedContentType Get(PublishedItemType itemType, string alias) { - var key = (itemType == PublishedItemType.Content ? "content" : "media") + "::" + alias.ToLowerInvariant(); - return ContentTypes.GetOrAdd(key, k => CreatePublishedContentType(itemType, alias)); + var key = string.Format("PublishedContentType_{0}_{1}", + itemType == PublishedItemType.Content ? "content" : "media", alias.ToLowerInvariant()); + + var type = ApplicationContext.Current.ApplicationCache.GetStaticCacheItem(key, + () => CreatePublishedContentType(itemType, alias)); + + return type; } private static PublishedContentType CreatePublishedContentType(PublishedItemType itemType, string alias) @@ -154,7 +151,10 @@ namespace Umbraco.Core.Models.PublishedContent get { return _getPublishedContentTypeCallBack; } set { - ClearAll(); + // see note above + //ClearAll(); + ApplicationContext.Current.ApplicationCache.ClearStaticCacheByKeySearch("PublishedContentType_"); + _getPublishedContentTypeCallBack = value; } } diff --git a/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs index 1474c1a16b..68d71032fd 100644 --- a/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs @@ -7,6 +7,7 @@ using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; +using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.Caching; using Umbraco.Web.PublishedCache; @@ -130,6 +131,11 @@ namespace Umbraco.Web.Cache //clear static object cache global::umbraco.cms.businesslogic.ContentType.RemoveAllDataTypeCache(); + // see PublishedContentType for details + // can do by object types - noone else should cache published content type + //ApplicationContext.Current.ApplicationCache.ClearStaticCacheByKeySearch("PublishedContentType_"); + ApplicationContext.Current.ApplicationCache.ClearStaticCacheObjectTypes(); + base.RefreshAll(); } @@ -250,6 +256,10 @@ namespace Umbraco.Web.Cache //clears the dictionary object cache of the legacy ContentType global::umbraco.cms.businesslogic.ContentType.RemoveFromDataTypeCache(payload.Alias); + // see PublishedContentType for details + ApplicationContext.Current.ApplicationCache.ClearStaticCacheObjectTypes( + (key, value) => value.Id == payload.Id); // faster than key strings comparisons + //need to recursively clear the cache for each child content type foreach (var descendant in payload.DescendantPayloads) { diff --git a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs index fb792fac27..f17d3c3ebb 100644 --- a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs @@ -4,6 +4,7 @@ using Umbraco.Core; using Umbraco.Core.Cache; using System.Linq; using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; namespace Umbraco.Web.Cache { @@ -121,6 +122,10 @@ namespace Umbraco.Web.Cache string.Format("{0}{1}", CacheKeys.DataTypeCacheKey, payload.Id)); ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch( string.Format("{0}{1}", CacheKeys.DataTypeCacheKey, payload.UniqueId)); + + // see PublishedContentType for details + ApplicationContext.Current.ApplicationCache.ClearStaticCacheObjectTypes( + (key, value) => value.PropertyTypes.Any(x => x.DataTypeId == payload.Id)); }); base.Refresh(jsonPayload); diff --git a/src/Umbraco.Web/Models/PublishedContentTypeCaching.cs b/src/Umbraco.Web/Models/PublishedContentTypeCaching.cs deleted file mode 100644 index a9cefa9fc6..0000000000 --- a/src/Umbraco.Web/Models/PublishedContentTypeCaching.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Models; -using Umbraco.Core.Models.PublishedContent; -using Umbraco.Core.Sync; -using Umbraco.Web.Cache; - -namespace Umbraco.Web.Models -{ - // note - // this is probably how we should refresh the Core.Models.PublishedContentType cache, by subscribing to - // events from the ContentTypeCacheRefresher - however as of may 1st, 2013 that eventing system is not - // fully operational and Shannon prefers that the refresh code is hard-wired into the refresher. so this - // is commented out and the refresher calls PublishedContentType.Clear() directly. - // FIXME - must refactor this class to use proper cache refresher - - class PublishedContentTypeCaching : ApplicationEventHandler - { - protected override void ApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) - { - ContentTypeCacheRefresher.CacheUpdated += ContentTypeCacheUpdated; - DataTypeCacheRefresher.CacheUpdated += DataTypeCacheUpdated; - base.ApplicationInitialized(umbracoApplication, applicationContext); - } - - private static void ContentTypeCacheUpdated(ContentTypeCacheRefresher sender, CacheRefresherEventArgs e) - { - switch (e.MessageType) - { - case MessageType.RefreshAll: - PublishedContentType.ClearAll(); - break; - case MessageType.RefreshById: - case MessageType.RemoveById: - PublishedContentType.ClearContentType((int)e.MessageObject); - break; - case MessageType.RefreshByInstance: - case MessageType.RemoveByInstance: - PublishedContentType.ClearContentType(((IContentType)e.MessageObject).Id); - break; - case MessageType.RefreshByJson: - var jsonPayload = (string)e.MessageObject; - // TODO ?? FUCK! this is what we get now what? - break; - default: - throw new ArgumentOutOfRangeException("e", "Unknown message type."); - } - } - - private static void DataTypeCacheUpdated(DataTypeCacheRefresher sender, CacheRefresherEventArgs e) - { - switch (e.MessageType) - { - case MessageType.RefreshAll: - PublishedContentType.ClearAll(); - break; - case MessageType.RefreshById: - case MessageType.RemoveById: - PublishedContentType.ClearDataType((int)e.MessageObject); - break; - case MessageType.RefreshByInstance: - case MessageType.RemoveByInstance: - PublishedContentType.ClearDataType(((IDataTypeDefinition)e.MessageObject).Id); - break; - case MessageType.RefreshByJson: - var jsonPayload = (string)e.MessageObject; - // TODO ?? - break; - default: - throw new ArgumentOutOfRangeException("e", "Unknown message type."); - } - } - } -} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index e9ea0b16dc..5387d36d2a 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -347,7 +347,6 @@ -