PublishedContent - proper PublishedContentType cache management
This commit is contained in:
@@ -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<string, PublishedContentType> ContentTypes = new ConcurrentDictionary<string, PublishedContentType>();
|
||||
|
||||
// internal, called by PublishedContentTypeCaching
|
||||
internal static void ClearAll()
|
||||
{
|
||||
Logging.LogHelper.Debug<PublishedContentType>("Clear all.");
|
||||
ContentTypes.Clear();
|
||||
}
|
||||
//// internal, called by ContentTypeCacheRefresher
|
||||
//internal static void ClearAll()
|
||||
//{
|
||||
// Logging.LogHelper.Debug<PublishedContentType>("Clear all.");
|
||||
// ApplicationContext.Current.ApplicationCache.ClearStaticCacheByKeySearch("PublishedContentType_");
|
||||
//}
|
||||
|
||||
// internal, called by PublishedContentTypeCaching
|
||||
internal static void ClearContentType(int id)
|
||||
{
|
||||
Logging.LogHelper.Debug<PublishedContentType>("Clear content type w/id {0}.", () => id);
|
||||
//// internal, called by ContentTypeCacheRefresher
|
||||
//internal static void ClearContentType(int id)
|
||||
//{
|
||||
// Logging.LogHelper.Debug<PublishedContentType>("Clear content type w/id {0}.", () => id);
|
||||
// // requires a predicate because the key does not contain the ID
|
||||
// ApplicationContext.Current.ApplicationCache.ClearStaticCacheObjectTypes<PublishedContentType>(
|
||||
// (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<PublishedContentType>("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<PublishedContentType>("Clear data type w/id {0}.", () => id);
|
||||
// ApplicationContext.Current.ApplicationCache.ClearStaticCacheObjectTypes<PublishedContentType>(
|
||||
// (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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<PublishedContentType>();
|
||||
|
||||
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<PublishedContentType>(
|
||||
(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)
|
||||
{
|
||||
|
||||
@@ -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<PublishedContentType>(
|
||||
(key, value) => value.PropertyTypes.Any(x => x.DataTypeId == payload.Id));
|
||||
});
|
||||
|
||||
base.Refresh(jsonPayload);
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,7 +347,6 @@
|
||||
<Compile Include="Models\DynamicPublishedContentList.cs" />
|
||||
<Compile Include="Models\PartialViewMacroModel.cs" />
|
||||
<Compile Include="Models\PublishedContentBase.cs" />
|
||||
<Compile Include="Models\PublishedContentTypeCaching.cs" />
|
||||
<Compile Include="Mvc\AreaRegistrationExtensions.cs" />
|
||||
<Compile Include="BaseRest\Configuration\BaseRestSection.cs" />
|
||||
<Compile Include="BaseRest\BaseRestHandler.cs" />
|
||||
|
||||
Reference in New Issue
Block a user