From 5f242aa3f6deb74630167fddf70619cb5ca0f7fd Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Thu, 21 Mar 2013 22:53:58 +0600 Subject: [PATCH] Converts the media cache refresher to be a json cache refresher since it was impossible before to have media cache cleared when media was deleted. Created base classes for cache refreshers, we now have a new event - CacheUpdated which can now be used by code to execute on each individual server when any cache refresher is updated. Listening to events normally only fire on the individual server so if people are wanting to refresh their own cache there was previously no way to do that. --- src/Umbraco.Core/Cache/CacheRefresherBase.cs | 67 ++++++++ .../Cache/CacheRefresherEventArgs.cs | 19 +++ .../Cache/JsonCacheRefresherBase.cs | 25 +++ .../Cache/TypedCacheRefresherBase.cs | 25 +++ src/Umbraco.Core/Models/Template.cs | 2 +- src/Umbraco.Core/Sync/MessageType.cs | 6 +- src/Umbraco.Core/Umbraco.Core.csproj | 4 + .../Cache/ContentTypeCacheRefresher.cs | 35 ++-- .../Cache/DistributedCacheExtensions.cs | 54 +++---- src/Umbraco.Web/Cache/MacroCacheRefresher.cs | 150 +++++++++++++----- src/Umbraco.Web/Cache/MediaCacheRefresher.cs | 127 +++++++++++---- src/Umbraco.Web/Cache/MemberCacheRefresher.cs | 38 ++--- src/Umbraco.Web/Cache/PageCacheRefresher.cs | 38 ++--- .../Cache/TemplateCacheRefresher.cs | 26 ++- src/Umbraco.Web/Cache/UserCacheRefresher.cs | 24 +-- 15 files changed, 442 insertions(+), 198 deletions(-) create mode 100644 src/Umbraco.Core/Cache/CacheRefresherBase.cs create mode 100644 src/Umbraco.Core/Cache/CacheRefresherEventArgs.cs create mode 100644 src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs create mode 100644 src/Umbraco.Core/Cache/TypedCacheRefresherBase.cs diff --git a/src/Umbraco.Core/Cache/CacheRefresherBase.cs b/src/Umbraco.Core/Cache/CacheRefresherBase.cs new file mode 100644 index 0000000000..2931805b08 --- /dev/null +++ b/src/Umbraco.Core/Cache/CacheRefresherBase.cs @@ -0,0 +1,67 @@ +using System; +using Umbraco.Core.Events; +using Umbraco.Core.Sync; +using umbraco.interfaces; + +namespace Umbraco.Core.Cache +{ + /// + /// A base class for cache refreshers to inherit from that ensures the correct events are raised + /// when cache refreshing occurs. + /// + /// The real cache refresher type, this is used for raising strongly typed events + public abstract class CacheRefresherBase : ICacheRefresher + where TInstanceType : ICacheRefresher + { + /// + /// An event that is raised when cache is updated on an individual server + /// + /// + /// This event will fire on each server configured for an Umbraco project whenever a cache refresher + /// is updated. + /// + public static event TypedEventHandler CacheUpdated; + + /// + /// Raises the event + /// + /// + /// + protected static void OnCacheUpdated(TInstanceType sender, CacheRefresherEventArgs args) + { + if (CacheUpdated != null) + { + CacheUpdated(sender, args); + } + } + + /// + /// Returns the real instance of the object ('this') for use in strongly typed events + /// + protected abstract TInstanceType Instance { get; } + + public abstract Guid UniqueIdentifier { get; } + + public abstract string Name { get; } + + public virtual void RefreshAll() + { + OnCacheUpdated(Instance, new CacheRefresherEventArgs(null, MessageType.RefreshAll)); + } + + public virtual void Refresh(int id) + { + OnCacheUpdated(Instance, new CacheRefresherEventArgs(id, MessageType.RefreshById)); + } + + public virtual void Remove(int id) + { + OnCacheUpdated(Instance, new CacheRefresherEventArgs(id, MessageType.RemoveById)); + } + + public virtual void Refresh(Guid id) + { + OnCacheUpdated(Instance, new CacheRefresherEventArgs(id, MessageType.RefreshById)); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Cache/CacheRefresherEventArgs.cs b/src/Umbraco.Core/Cache/CacheRefresherEventArgs.cs new file mode 100644 index 0000000000..09d9226002 --- /dev/null +++ b/src/Umbraco.Core/Cache/CacheRefresherEventArgs.cs @@ -0,0 +1,19 @@ +using System; +using Umbraco.Core.Sync; + +namespace Umbraco.Core.Cache +{ + /// + /// Event args for cache refresher updates + /// + public class CacheRefresherEventArgs : EventArgs + { + public CacheRefresherEventArgs(object msgObject, MessageType type) + { + MessageType = type; + MessageObject = msgObject; + } + public object MessageObject { get; private set; } + public MessageType MessageType { get; private set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs b/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs new file mode 100644 index 0000000000..72c484645b --- /dev/null +++ b/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs @@ -0,0 +1,25 @@ +using Umbraco.Core.Sync; +using umbraco.interfaces; + +namespace Umbraco.Core.Cache +{ + /// + /// A base class for json cache refreshers that ensures the correct events are raised when + /// cache refreshing occurs. + /// + /// The real cache refresher type, this is used for raising strongly typed events + public abstract class JsonCacheRefresherBase : CacheRefresherBase, IJsonCacheRefresher + where TInstanceType : ICacheRefresher + { + + public virtual void Refresh(string jsonPayload) + { + OnCacheUpdated(Instance, new CacheRefresherEventArgs(jsonPayload, MessageType.RefreshByJson)); + } + + public virtual void Remove(string jsonPayload) + { + OnCacheUpdated(Instance, new CacheRefresherEventArgs(jsonPayload, MessageType.RemoveByJson)); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Cache/TypedCacheRefresherBase.cs b/src/Umbraco.Core/Cache/TypedCacheRefresherBase.cs new file mode 100644 index 0000000000..ba7b0a5a6b --- /dev/null +++ b/src/Umbraco.Core/Cache/TypedCacheRefresherBase.cs @@ -0,0 +1,25 @@ +using Umbraco.Core.Sync; +using umbraco.interfaces; + +namespace Umbraco.Core.Cache +{ + /// + /// A base class for cache refreshers to inherit from that ensures the correct events are raised + /// when cache refreshing occurs. + /// + /// The real cache refresher type, this is used for raising strongly typed events + /// The entity type that this refresher can update cache for + public abstract class TypedCacheRefresherBase : CacheRefresherBase, ICacheRefresher + where TInstanceType : ICacheRefresher + { + public virtual void Refresh(TEntityType instance) + { + OnCacheUpdated(Instance, new CacheRefresherEventArgs(instance, MessageType.RefreshByInstance)); + } + + public virtual void Remove(TEntityType instance) + { + OnCacheUpdated(Instance, new CacheRefresherEventArgs(instance, MessageType.RemoveByInstance)); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Template.cs b/src/Umbraco.Core/Models/Template.cs index be111bfc26..33f203d6de 100644 --- a/src/Umbraco.Core/Models/Template.cs +++ b/src/Umbraco.Core/Models/Template.cs @@ -29,7 +29,7 @@ namespace Umbraco.Core.Models private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo(x => x.SortOrder); private static readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo(x => x.ParentId); private static readonly PropertyInfo NodePathSelector = ExpressionHelper.GetPropertyInfo(x => x.NodePath); - private static readonly PropertyInfo MasterTemplateIdSelector = ExpressionHelper.GetPropertyInfo(x => x.MasterTemplateId); + //private static readonly PropertyInfo MasterTemplateIdSelector = ExpressionHelper.GetPropertyInfo(x => x.MasterTemplateId); private static readonly PropertyInfo MasterTemplateAliasSelector = ExpressionHelper.GetPropertyInfo(x => x.MasterTemplateAlias); diff --git a/src/Umbraco.Core/Sync/MessageType.cs b/src/Umbraco.Core/Sync/MessageType.cs index 8b0b69a026..3c107fba8c 100644 --- a/src/Umbraco.Core/Sync/MessageType.cs +++ b/src/Umbraco.Core/Sync/MessageType.cs @@ -3,12 +3,14 @@ /// /// The message type to be used for syncing across servers /// - internal enum MessageType + public enum MessageType { RefreshAll, RefreshById, RefreshByJson, RemoveById, - RemoveByJson + RemoveByJson, + RefreshByInstance, + RemoveByInstance } } \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 8c26a1824c..c4051b4c3e 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -109,7 +109,11 @@ + + + + diff --git a/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs index ecf7a8d03f..6be3dbde92 100644 --- a/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs @@ -21,7 +21,7 @@ namespace Umbraco.Web.Cache /// /// This is not intended to be used directly in your code /// - public sealed class ContentTypeCacheRefresher : IJsonCacheRefresher + public sealed class ContentTypeCacheRefresher : JsonCacheRefresherBase { #region Static helpers @@ -105,16 +105,21 @@ namespace Umbraco.Web.Cache #endregion - public Guid UniqueIdentifier + protected override ContentTypeCacheRefresher Instance + { + get { return this; } + } + + public override Guid UniqueIdentifier { get { return new Guid(DistributedCache.ContentTypeCacheRefresherId); } } - public string Name + public override string Name { get { return "ContentTypeCacheRefresher"; } } - public void RefreshAll() + public override void RefreshAll() { //all property type cache ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(CacheKeys.PropertyTypeCacheKey); @@ -124,40 +129,42 @@ namespace Umbraco.Web.Cache ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(CacheKeys.ContentTypeCacheKey); //clear static object cache global::umbraco.cms.businesslogic.ContentType.RemoveAllDataTypeCache(); + + base.RefreshAll(); } - public void Refresh(int id) + public override void Refresh(int id) { ClearContentTypeCache(false, id); + base.Refresh(id); } - public void Remove(int id) + public override void Remove(int id) { ClearContentTypeCache(true, id); + base.Remove(id); } - public void Refresh(Guid id) - { - } - /// /// Refreshes the cache using the custom jsonPayload provided /// /// - public void Refresh(string jsonPayload) + public override void Refresh(string jsonPayload) { var payload = DeserializeFromJsonPayload(jsonPayload); ClearContentTypeCache(payload); + base.Refresh(jsonPayload); } /// /// Removes the cache using the custom jsonPayload provided /// /// - public void Remove(string jsonPayload) + public override void Remove(string jsonPayload) { var payload = DeserializeFromJsonPayload(jsonPayload); ClearContentTypeCache(payload); + base.Remove(jsonPayload); } /// @@ -173,10 +180,6 @@ namespace Umbraco.Web.Cache /// - InMemoryCacheProvider.Current.Clear(); /// - RuntimeCacheProvider.Current.Clear(); /// - RoutesCache.Clear(); - /// - /// TODO: Needs to update any content items that this effects for the xml cache... - /// it is only handled in the ContentTypeControlNew.ascx, not by business logic/events. - The xml cache needs to be updated - /// when the doc type alias changes or when a property type is removed, the ContentService.RePublishAll should be executed anytime either of these happens. /// private static void ClearContentTypeCache(IEnumerable payloads) { diff --git a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs index 9d1cd2efeb..53ab7adf27 100644 --- a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs +++ b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs @@ -120,16 +120,7 @@ namespace Umbraco.Web.Cache #endregion #region Media Cache - /// - /// Refreshes the cache amongst servers for a media item - /// - /// - /// - public static void RefreshMediaCache(this DistributedCache dc, int mediaId) - { - dc.Refresh(new Guid(DistributedCache.MediaCacheRefresherId), mediaId); - } - + /// /// Refreshes the cache amongst servers for a media item /// @@ -137,7 +128,8 @@ namespace Umbraco.Web.Cache /// public static void RefreshMediaCache(this DistributedCache dc, params IMedia[] media) { - dc.Refresh(new Guid(DistributedCache.MediaCacheRefresherId), x => x.Id, media); + dc.RefreshByJson(new Guid(DistributedCache.MediaCacheRefresherId), + MediaCacheRefresher.SerializeToJsonPayload(media)); } /// @@ -145,6 +137,11 @@ namespace Umbraco.Web.Cache /// /// /// + /// + /// Clearing by Id will never work for load balanced scenarios for media since we require a Path + /// to clear all of the cache but the media item will be removed before the other servers can + /// look it up. Only here for legacy purposes. + /// public static void RemoveMediaCache(this DistributedCache dc, int mediaId) { dc.Remove(new Guid(DistributedCache.MediaCacheRefresherId), mediaId); @@ -157,8 +154,10 @@ namespace Umbraco.Web.Cache /// public static void RemoveMediaCache(this DistributedCache dc, params IMedia[] media) { - dc.Remove(new Guid(DistributedCache.MediaCacheRefresherId), x => x.Id, media); + dc.RemoveByJson(new Guid(DistributedCache.MediaCacheRefresherId), + MediaCacheRefresher.SerializeToJsonPayload(media)); } + #endregion #region Macro Cache @@ -173,16 +172,6 @@ namespace Umbraco.Web.Cache dc.RefreshAll(new Guid(DistributedCache.MacroCacheRefresherId), false); } - /// - /// Refreshes the cache amongst servers for a macro item - /// - /// - /// - public static void RefreshMacroCache(this DistributedCache dc, int macroId) - { - dc.Refresh(new Guid(DistributedCache.MacroCacheRefresherId), macroId); - } - /// /// Refreshes the cache amongst servers for a macro item /// @@ -192,20 +181,11 @@ namespace Umbraco.Web.Cache { if (macro != null) { - dc.Refresh(new Guid(DistributedCache.MacroCacheRefresherId), macro1 => macro1.Id, macro); + dc.RefreshByJson(new Guid(DistributedCache.MacroCacheRefresherId), + MacroCacheRefresher.SerializeToJsonPayload(macro)); } } - - /// - /// Removes the cache amongst servers for a macro item - /// - /// - /// - public static void RemoveMacroCache(this DistributedCache dc, int macroId) - { - dc.Remove(new Guid(DistributedCache.MacroCacheRefresherId), macroId); - } - + /// /// Removes the cache amongst servers for a macro item /// @@ -215,7 +195,8 @@ namespace Umbraco.Web.Cache { if (macro != null) { - dc.Remove(new Guid(DistributedCache.MacroCacheRefresherId), macro1 => macro1.Id, macro); + dc.RemoveByJson(new Guid(DistributedCache.MacroCacheRefresherId), + MacroCacheRefresher.SerializeToJsonPayload(macro)); } } @@ -228,7 +209,8 @@ namespace Umbraco.Web.Cache { if (macro != null && macro.Model != null) { - dc.Remove(new Guid(DistributedCache.MacroCacheRefresherId), macro1 => macro1.Model.Id, macro); + dc.RemoveByJson(new Guid(DistributedCache.MacroCacheRefresherId), + MacroCacheRefresher.SerializeToJsonPayload(macro)); } } #endregion diff --git a/src/Umbraco.Web/Cache/MacroCacheRefresher.cs b/src/Umbraco.Web/Cache/MacroCacheRefresher.cs index e884ab4a7f..850f56f84d 100644 --- a/src/Umbraco.Web/Cache/MacroCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/MacroCacheRefresher.cs @@ -1,4 +1,5 @@ using System; +using System.Web.Script.Serialization; using Umbraco.Core; using Umbraco.Core.Cache; using umbraco; @@ -14,8 +15,10 @@ namespace Umbraco.Web.Cache /// /// This is not intended to be used directly in your code and it should be sealed but due to legacy code we cannot seal it. /// - public class MacroCacheRefresher : ICacheRefresher, ICacheRefresher + public class MacroCacheRefresher : JsonCacheRefresherBase { + #region Static helpers + internal static string[] GetAllMacroCacheKeys() { return new[] @@ -33,7 +36,92 @@ namespace Umbraco.Web.Cache return GetAllMacroCacheKeys().Select(x => x + alias).ToArray(); } - public string Name + /// + /// Converts the json to a JsonPayload object + /// + /// + /// + private static JsonPayload[] DeserializeFromJsonPayload(string json) + { + var serializer = new JavaScriptSerializer(); + var jsonObject = serializer.Deserialize(json); + return jsonObject; + } + + /// + /// Creates the custom Json payload used to refresh cache amongst the servers + /// + /// + /// + internal static string SerializeToJsonPayload(params Macro[] macros) + { + var serializer = new JavaScriptSerializer(); + var items = macros.Select(FromMacro).ToArray(); + var json = serializer.Serialize(items); + return json; + } + + /// + /// Creates the custom Json payload used to refresh cache amongst the servers + /// + /// + /// + internal static string SerializeToJsonPayload(params macro[] macros) + { + var serializer = new JavaScriptSerializer(); + var items = macros.Select(FromMacro).ToArray(); + var json = serializer.Serialize(items); + return json; + } + + /// + /// Converts a macro to a jsonPayload object + /// + /// + /// + private static JsonPayload FromMacro(Macro macro) + { + var payload = new JsonPayload + { + Alias = macro.Alias, + Id = macro.Id + }; + return payload; + } + + /// + /// Converts a macro to a jsonPayload object + /// + /// + /// + private static JsonPayload FromMacro(macro macro) + { + var payload = new JsonPayload + { + Alias = macro.Alias, + Id = macro.Model.Id + }; + return payload; + } + + #endregion + + #region Sub classes + + private class JsonPayload + { + public string Alias { get; set; } + public int Id { get; set; } + } + + #endregion + + protected override MacroCacheRefresher Instance + { + get { return this; } + } + + public override string Name { get { @@ -41,7 +129,7 @@ namespace Umbraco.Web.Cache } } - public Guid UniqueIdentifier + public override Guid UniqueIdentifier { get { @@ -49,60 +137,34 @@ namespace Umbraco.Web.Cache } } - public void RefreshAll() + public override void RefreshAll() { ApplicationContext.Current.ApplicationCache.ClearCacheObjectTypes(); GetAllMacroCacheKeys().ForEach( prefix => ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(prefix)); + + base.RefreshAll(); } - public void Refresh(Guid id) + public override void Refresh(string jsonPayload) { + Remove(jsonPayload); + base.Refresh(jsonPayload); } - public void Refresh(int id) + public override void Remove(string jsonPayload) { - if (id <= 0) return; - var m = new Macro(id); - Remove(m); - } + var payloads = DeserializeFromJsonPayload(jsonPayload); - public void Remove(int id) - { - if (id <= 0) return; - var m = new Macro(id); - Remove(m); - } + payloads.ForEach(payload => + { + GetCacheKeysForAlias(payload.Alias).ForEach( + alias => + ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(alias)); + }); - public void Refresh(Macro instance) - { - Remove(instance); - } - - public void Remove(Macro instance) - { - if (instance != null && instance.Id > 0) - { - GetCacheKeysForAlias(instance.Alias).ForEach( - alias => - ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(alias)); - - } - } - - public void Refresh(macro instance) - { - Remove(instance); - } - - public void Remove(macro instance) - { - if (instance == null || instance.Model == null) return; - var m = instance.Model; - GetCacheKeysForAlias(m.Alias).ForEach( - alias => - ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(alias)); + base.Remove(jsonPayload); } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Cache/MediaCacheRefresher.cs b/src/Umbraco.Web/Cache/MediaCacheRefresher.cs index 7382a39427..fab9e6264d 100644 --- a/src/Umbraco.Web/Cache/MediaCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/MediaCacheRefresher.cs @@ -1,73 +1,138 @@ using System; +using System.Collections.Generic; +using System.Web.Script.Serialization; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Models; using umbraco.interfaces; +using System.Linq; namespace Umbraco.Web.Cache { /// - /// A cache refresher to ensure media cache is updated when members change + /// A cache refresher to ensure media cache is updated /// /// /// This is not intended to be used directly in your code and it should be sealed but due to legacy code we cannot seal it. /// - public class MediaCacheRefresher : ICacheRefresher + public class MediaCacheRefresher : JsonCacheRefresherBase { - public Guid UniqueIdentifier + #region Static helpers + + /// + /// Converts the json to a JsonPayload object + /// + /// + /// + private static JsonPayload[] DeserializeFromJsonPayload(string json) + { + var serializer = new JavaScriptSerializer(); + var jsonObject = serializer.Deserialize(json); + return jsonObject; + } + + /// + /// Creates the custom Json payload used to refresh cache amongst the servers + /// + /// + /// + internal static string SerializeToJsonPayload(params IMedia[] media) + { + var serializer = new JavaScriptSerializer(); + var items = media.Select(FromMedia).ToArray(); + var json = serializer.Serialize(items); + return json; + } + + /// + /// Converts a macro to a jsonPayload object + /// + /// + /// + private static JsonPayload FromMedia(IMedia media) + { + if (media == null) return null; + + var payload = new JsonPayload + { + Id = media.Id, + Path = media.Path + }; + return payload; + } + + #endregion + + #region Sub classes + + private class JsonPayload + { + public string Path { get; set; } + public int Id { get; set; } + } + + #endregion + + protected override MediaCacheRefresher Instance + { + get { return this; } + } + + public override Guid UniqueIdentifier { get { return new Guid(DistributedCache.MediaCacheRefresherId); } } - public string Name + public override string Name { get { return "Clears Media Cache from umbraco.library"; } } - public void RefreshAll() + public override void Refresh(string jsonPayload) { + ClearCache(DeserializeFromJsonPayload(jsonPayload)); + base.Refresh(jsonPayload); } - public void Refresh(int id) + public override void Remove(string jsonPayload) { - ClearCache(ApplicationContext.Current.Services.MediaService.GetById(id)); + ClearCache(DeserializeFromJsonPayload(jsonPayload)); + base.Remove(jsonPayload); } - public void Remove(int id) + public override void Refresh(int id) { - ClearCache(ApplicationContext.Current.Services.MediaService.GetById(id)); + ClearCache(FromMedia(ApplicationContext.Current.Services.MediaService.GetById(id))); + base.Refresh(id); } - public void Refresh(Guid id) + public override void Remove(int id) { + ClearCache(FromMedia(ApplicationContext.Current.Services.MediaService.GetById(id))); + base.Remove(id); } - - public void Refresh(IMedia instance) + + private static void ClearCache(params JsonPayload[] payloads) { - ClearCache(instance); - } + if (payloads == null) return; - public void Remove(IMedia instance) - { - ClearCache(instance); - } + payloads.ForEach(payload => + { + foreach (var idPart in payload.Path.Split(',')) + { + ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch( + string.Format("{0}_{1}_True", CacheKeys.MediaCacheKey, idPart)); - private static void ClearCache(IMedia media) - { - if (media == null) return; + // Also clear calls that only query this specific item! + if (idPart == payload.Id.ToString()) + ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch( + string.Format("{0}_{1}", CacheKeys.MediaCacheKey, payload.Id)); - foreach (var idPart in media.Path.Split(',')) - { - ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch( - string.Format("{0}_{1}_True", CacheKeys.MediaCacheKey, idPart)); + } + }); - // Also clear calls that only query this specific item! - if (idPart == media.Id.ToString()) - ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch( - string.Format("{0}_{1}", CacheKeys.MediaCacheKey, media.Id)); - - } + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Cache/MemberCacheRefresher.cs b/src/Umbraco.Web/Cache/MemberCacheRefresher.cs index ccdb9e1ae9..9bc6fe6418 100644 --- a/src/Umbraco.Web/Cache/MemberCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/MemberCacheRefresher.cs @@ -12,36 +12,34 @@ namespace Umbraco.Web.Cache /// /// This is not intended to be used directly in your code and it should be sealed but due to legacy code we cannot seal it. /// - public class MemberCacheRefresher : ICacheRefresher + public class MemberCacheRefresher : CacheRefresherBase { - public Guid UniqueIdentifier + protected override MemberCacheRefresher Instance + { + get { return this; } + } + + public override Guid UniqueIdentifier { get { return new Guid(DistributedCache.MemberCacheRefresherId); } } - public string Name + public override string Name { get { return "Clears Member Cache from umbraco.library"; } } - - public void RefreshAll() - { - } - - public void Refresh(int id) + + public override void Refresh(int id) { ClearCache(id); + base.Refresh(id); } - public void Remove(int id) + public override void Remove(int id) { ClearCache(id); - } - - public void Refresh(Guid id) - { - + base.Remove(id); } private void ClearCache(int id) @@ -49,15 +47,5 @@ namespace Umbraco.Web.Cache ApplicationContext.Current.ApplicationCache. ClearCacheByKeySearch(string.Format("{0}_{1}", CacheKeys.MemberCacheKey, id)); } - - public void Refresh(Member instance) - { - throw new NotImplementedException(); - } - - public void Remove(Member instance) - { - throw new NotImplementedException(); - } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Cache/PageCacheRefresher.cs b/src/Umbraco.Web/Cache/PageCacheRefresher.cs index bf709757e1..0d1530b8ce 100644 --- a/src/Umbraco.Web/Cache/PageCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/PageCacheRefresher.cs @@ -16,13 +16,19 @@ namespace Umbraco.Web.Cache /// If Load balancing is enabled (by default disabled, is set in umbracoSettings.config) PageCacheRefresher will be called /// everytime content is added/updated/removed to ensure that the content cache is identical on all load balanced servers /// - public class PageCacheRefresher : ICacheRefresher - { + public class PageCacheRefresher : TypedCacheRefresherBase + { + + protected override PageCacheRefresher Instance + { + get { return this; } + } + /// /// Gets the unique identifier of the CacheRefresher. /// /// The unique identifier. - public Guid UniqueIdentifier + public override Guid UniqueIdentifier { get { @@ -34,7 +40,7 @@ namespace Umbraco.Web.Cache /// Gets the name of the CacheRefresher /// /// The name. - public string Name + public override string Name { get { return "Page Refresher"; } } @@ -42,46 +48,42 @@ namespace Umbraco.Web.Cache /// /// Refreshes all nodes in umbraco. /// - public void RefreshAll() + public override void RefreshAll() { content.Instance.RefreshContentFromDatabaseAsync(); - } - - /// - /// Not used with content. - /// - /// The id. - public void Refresh(Guid id) - { - // Not used when pages + base.RefreshAll(); } /// /// Refreshes the cache for the node with specified id /// /// The id. - public void Refresh(int id) + public override void Refresh(int id) { content.Instance.UpdateDocumentCache(id); + base.Refresh(id); } /// /// Removes the node with the specified id from the cache /// /// The id. - public void Remove(int id) + public override void Remove(int id) { content.Instance.ClearDocumentCache(id); + base.Remove(id); } - public void Refresh(IContent instance) + public override void Refresh(IContent instance) { content.Instance.UpdateDocumentCache(new Document(instance)); + base.Refresh(instance); } - public void Remove(IContent instance) + public override void Remove(IContent instance) { content.Instance.ClearDocumentCache(new Document(instance)); + base.Remove(instance); } } } diff --git a/src/Umbraco.Web/Cache/TemplateCacheRefresher.cs b/src/Umbraco.Web/Cache/TemplateCacheRefresher.cs index 8b2507ddbf..5b4c1c3110 100644 --- a/src/Umbraco.Web/Cache/TemplateCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/TemplateCacheRefresher.cs @@ -13,10 +13,14 @@ namespace Umbraco.Web.Cache /// /// This is not intended to be used directly in your code and it should be sealed but due to legacy code we cannot seal it. /// - public class TemplateCacheRefresher : ICacheRefresher + public class TemplateCacheRefresher : CacheRefresherBase { - - public string Name + protected override TemplateCacheRefresher Instance + { + get { return this; } + } + + public override string Name { get { @@ -24,7 +28,7 @@ namespace Umbraco.Web.Cache } } - public Guid UniqueIdentifier + public override Guid UniqueIdentifier { get { @@ -32,22 +36,16 @@ namespace Umbraco.Web.Cache } } - public void RefreshAll() - { - } - - public void Refresh(Guid id) - { - } - - public void Refresh(int id) + public override void Refresh(int id) { RemoveFromCache(id); + base.Refresh(id); } - public void Remove(int id) + public override void Remove(int id) { RemoveFromCache(id); + base.Remove(id); } private void RemoveFromCache(int id) diff --git a/src/Umbraco.Web/Cache/UserCacheRefresher.cs b/src/Umbraco.Web/Cache/UserCacheRefresher.cs index c9de3aa8e4..0525d34fa4 100644 --- a/src/Umbraco.Web/Cache/UserCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/UserCacheRefresher.cs @@ -8,35 +8,37 @@ namespace Umbraco.Web.Cache /// /// Handles User cache invalidation/refreshing /// - public sealed class UserCacheRefresher : ICacheRefresher + public sealed class UserCacheRefresher : CacheRefresherBase { - public Guid UniqueIdentifier + protected override UserCacheRefresher Instance + { + get { return this; } + } + + public override Guid UniqueIdentifier { get { return Guid.Parse(DistributedCache.UserCacheRefresherId); } } - public string Name + + public override string Name { get { return "User cache refresher"; } } - public void RefreshAll() + public override void RefreshAll() { ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(CacheKeys.UserCacheKey); } - public void Refresh(int id) + public override void Refresh(int id) { Remove(id); } - public void Remove(int id) + public override void Remove(int id) { - ApplicationContext.Current.ApplicationCache.ClearCacheItem(string.Format("{0}{1}", CacheKeys.UserCacheKey, id.ToString())); + ApplicationContext.Current.ApplicationCache.ClearCacheItem(string.Format("{0}{1}", CacheKeys.UserCacheKey, id)); } - public void Refresh(Guid id) - { - - } } } \ No newline at end of file