PublishedContent - proper PublishedContentType cache management

This commit is contained in:
Stephan
2013-09-18 10:07:04 +02:00
parent 0c28e01347
commit 1e786ac311
5 changed files with 49 additions and 110 deletions

View File

@@ -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;
}
}

View File

@@ -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)
{

View File

@@ -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);

View File

@@ -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.");
}
}
}
}

View File

@@ -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" />