From 0cda994538e6cbef670a97fcf4ef1b4dced90480 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Tue, 7 May 2013 19:37:57 -1000 Subject: [PATCH] Fixes DataTypeCacheRefresher to be a Json cache refresher since it needs to refresh both by GUID and by Int Ids --- .../Cache/CacheRefresherEventHandler.cs | 8 +- .../Cache/DataTypeCacheRefresher.cs | 111 +++++++++++++++--- .../Cache/DistributedCacheExtensions.cs | 52 ++++++-- 3 files changed, 145 insertions(+), 26 deletions(-) diff --git a/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs b/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs index 025748cf13..0f529b8840 100644 --- a/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs +++ b/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs @@ -203,22 +203,22 @@ namespace Umbraco.Web.Cache #region DataType event handlers static void DataTypeServiceSaved(IDataTypeService sender, Core.Events.SaveEventArgs e) { - e.SavedEntities.ForEach(x => DistributedCache.Instance.RefreshDataTypeCache(x.Id)); + e.SavedEntities.ForEach(x => DistributedCache.Instance.RefreshDataTypeCache(x)); } static void DataTypeServiceDeleted(IDataTypeService sender, Core.Events.DeleteEventArgs e) { - e.DeletedEntities.ForEach(x => DistributedCache.Instance.RemoveDataTypeCache(x.Id)); + e.DeletedEntities.ForEach(x => DistributedCache.Instance.RemoveDataTypeCache(x)); } static void DataTypeDefinitionSaving(global::umbraco.cms.businesslogic.datatype.DataTypeDefinition sender, System.EventArgs e) { - DistributedCache.Instance.RefreshDataTypeCache(sender.Id); + DistributedCache.Instance.RefreshDataTypeCache(sender); } static void DataTypeDefinitionDeleting(global::umbraco.cms.businesslogic.datatype.DataTypeDefinition sender, System.EventArgs e) { - DistributedCache.Instance.RemoveDataTypeCache(sender.Id); + DistributedCache.Instance.RemoveDataTypeCache(sender); } #endregion diff --git a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs index d0fbec43bd..fb792fac27 100644 --- a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs @@ -1,15 +1,100 @@ using System; +using System.Web.Script.Serialization; using Umbraco.Core; using Umbraco.Core.Cache; +using System.Linq; +using Umbraco.Core.Models; namespace Umbraco.Web.Cache { /// /// A cache refresher to ensure member cache is updated when members change /// - public sealed class DataTypeCacheRefresher : CacheRefresherBase + public sealed class DataTypeCacheRefresher : JsonCacheRefresherBase { + #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 global::umbraco.cms.businesslogic.datatype.DataTypeDefinition[] dataTypes) + { + var serializer = new JavaScriptSerializer(); + var items = dataTypes.Select(FromDataTypeDefinition).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 IDataTypeDefinition[] dataTypes) + { + var serializer = new JavaScriptSerializer(); + var items = dataTypes.Select(FromDataTypeDefinition).ToArray(); + var json = serializer.Serialize(items); + return json; + } + + /// + /// Converts a macro to a jsonPayload object + /// + /// + /// + private static JsonPayload FromDataTypeDefinition(global::umbraco.cms.businesslogic.datatype.DataTypeDefinition dataType) + { + var payload = new JsonPayload + { + UniqueId = dataType.UniqueId, + Id = dataType.Id + }; + return payload; + } + + /// + /// Converts a macro to a jsonPayload object + /// + /// + /// + private static JsonPayload FromDataTypeDefinition(IDataTypeDefinition dataType) + { + var payload = new JsonPayload + { + UniqueId = dataType.Key, + Id = dataType.Id + }; + return payload; + } + + #endregion + + #region Sub classes + + private class JsonPayload + { + public Guid UniqueId { get; set; } + public int Id { get; set; } + } + + #endregion + protected override DataTypeCacheRefresher Instance { get { return this; } @@ -25,22 +110,20 @@ namespace Umbraco.Web.Cache get { return "Clears data type cache"; } } - public override void Refresh(int id) + public override void Refresh(string jsonPayload) { - ClearCache(id); - base.Refresh(id); - } + var payloads = DeserializeFromJsonPayload(jsonPayload); - public override void Remove(int id) - { - ClearCache(id); - base.Remove(id); - } + payloads.ForEach(payload => + { + //clear both the Id and Unique Id cache since we cache both in the legacy classes :( + ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch( + string.Format("{0}{1}", CacheKeys.DataTypeCacheKey, payload.Id)); + ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch( + string.Format("{0}{1}", CacheKeys.DataTypeCacheKey, payload.UniqueId)); + }); - private void ClearCache(int id) - { - ApplicationContext.Current.ApplicationCache. - ClearCacheByKeySearch(string.Format("{0}{1}", CacheKeys.DataTypeCacheKey, id)); + base.Refresh(jsonPayload); } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs index f9ae3b8d6e..5e46927d57 100644 --- a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs +++ b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs @@ -110,23 +110,59 @@ namespace Umbraco.Web.Cache #region Data type cache /// - /// Refreshes the cache amongst servers for a template + /// Refreshes the cache amongst servers for a data type /// /// - /// - public static void RefreshDataTypeCache(this DistributedCache dc, int dataTypeId) + /// + public static void RefreshDataTypeCache(this DistributedCache dc, global::umbraco.cms.businesslogic.datatype.DataTypeDefinition dataType) { - dc.Refresh(new Guid(DistributedCache.DataTypeCacheRefresherId), dataTypeId); + if (dataType != null) + { + dc.RefreshByJson(new Guid(DistributedCache.DataTypeCacheRefresherId), + DataTypeCacheRefresher.SerializeToJsonPayload(dataType)); + } } /// - /// Removes the cache amongst servers for a template + /// Removes the cache amongst servers for a data type /// /// - /// - public static void RemoveDataTypeCache(this DistributedCache dc, int dataTypeId) + /// + public static void RemoveDataTypeCache(this DistributedCache dc, global::umbraco.cms.businesslogic.datatype.DataTypeDefinition dataType) { - dc.Remove(new Guid(DistributedCache.DataTypeCacheRefresherId), dataTypeId); + if (dataType != null) + { + dc.RefreshByJson(new Guid(DistributedCache.DataTypeCacheRefresherId), + DataTypeCacheRefresher.SerializeToJsonPayload(dataType)); + } + } + + /// + /// Refreshes the cache amongst servers for a data type + /// + /// + /// + public static void RefreshDataTypeCache(this DistributedCache dc, IDataTypeDefinition dataType) + { + if (dataType != null) + { + dc.RefreshByJson(new Guid(DistributedCache.DataTypeCacheRefresherId), + DataTypeCacheRefresher.SerializeToJsonPayload(dataType)); + } + } + + /// + /// Removes the cache amongst servers for a data type + /// + /// + /// + public static void RemoveDataTypeCache(this DistributedCache dc, IDataTypeDefinition dataType) + { + if (dataType != null) + { + dc.RefreshByJson(new Guid(DistributedCache.DataTypeCacheRefresherId), + DataTypeCacheRefresher.SerializeToJsonPayload(dataType)); + } } #endregion