Streamlines how macro cache is handled

This commit is contained in:
Shannon Deminick
2013-03-12 03:00:42 +04:00
parent 164f22aa50
commit ec46d65bb4
18 changed files with 167 additions and 141 deletions

View File

@@ -40,7 +40,7 @@ namespace Umbraco.Core
{
//create a new application cache from the HttpRuntime.Cache
ApplicationCache = HttpRuntime.Cache == null
? new CacheHelper(new Cache())
? new CacheHelper(new System.Web.Caching.Cache())
: new CacheHelper(HttpRuntime.Cache);
}

View File

@@ -0,0 +1,21 @@
namespace Umbraco.Core.Cache
{
/// <summary>
/// Constants storing cache keys used in caching
/// </summary>
public static class CacheKeys
{
public const string GetMediaCacheKey = "GetMedia";
//NOTE: pretty sure this is never used anymore
internal const string MacroRuntimeCacheKey = "UmbracoRuntimeMacroCache";
public const string UmbracoMacroCacheKey = "UmbracoMacroCache";
public const string GetMemberCacheKey = "GetMember";
public const string TemplateCacheKey = "template";
public const string UserCacheKey = "UmbracoUser";
}
}

View File

@@ -1,6 +1,6 @@
using umbraco.interfaces;
namespace Umbraco.Core.Sync
namespace Umbraco.Core.Cache
{
/// <summary>
/// Strongly type cache refresher that is able to refresh cache of real instances of objects as well as IDs

View File

@@ -18,7 +18,7 @@ namespace Umbraco.Core
/// </remarks>
public class CacheHelper
{
private readonly Cache _cache;
private readonly System.Web.Caching.Cache _cache;
public CacheHelper(System.Web.Caching.Cache cache)
{
@@ -173,7 +173,7 @@ namespace Umbraco.Core
{
//we use Insert instead of add if for some crazy reason there is now a cache with the cache key in there, it will just overwrite it.
_cache.Insert(cacheKey, result, cacheDependency,
timeout == null ? Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value),
timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value),
TimeSpan.Zero, priority, refreshAction);
}
}

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Net;
using System.Threading;
using System.Web.Script.Serialization;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using umbraco.interfaces;

View File

@@ -108,6 +108,7 @@
<Compile Include="Auditing\DataAuditWriteProvider.cs" />
<Compile Include="Auditing\IAuditWriteProvider.cs" />
<Compile Include="CacheHelper.cs" />
<Compile Include="Cache\CacheKeys.cs" />
<Compile Include="CodeAnnotations\UmbracoWillObsoleteAttribute.cs" />
<Compile Include="CodeAnnotations\UmbracoExperimentalFeatureAttribute.cs" />
<Compile Include="CodeAnnotations\UmbracoProposedPublicAttribute.cs" />
@@ -691,7 +692,7 @@
<Compile Include="Strings\UrlSegmentProviderResolver.cs" />
<Compile Include="Sync\DatabaseServerRegistrar.cs" />
<Compile Include="Sync\DefaultServerMessenger.cs" />
<Compile Include="Sync\ICacheRefresher.cs" />
<Compile Include="Cache\ICacheRefresher.cs" />
<Compile Include="Sync\ServerSyncWebServiceClient.cs">
<SubType>Component</SubType>
</Compile>

View File

@@ -87,7 +87,7 @@ namespace Umbraco.Web.Cache
/// <param name="e"></param>
static void MacroAfterDelete(Macro sender, DeleteEventArgs e)
{
DistributedCache.Instance.RemoveMacroCache(sender.Id);
DistributedCache.Instance.RemoveMacroCache(sender);
}
/// <summary>
@@ -97,7 +97,7 @@ namespace Umbraco.Web.Cache
/// <param name="e"></param>
static void MacroAfterSave(Macro sender, SaveEventArgs e)
{
DistributedCache.Instance.RefreshMacroCache(sender.Id);
DistributedCache.Instance.RefreshMacroCache(sender);
}
static void MediaServiceTrashing(IMediaService sender, Core.Events.MoveEventArgs<Core.Models.IMedia> e)

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Models;
using umbraco;
namespace Umbraco.Web.Cache
{
@@ -159,6 +160,19 @@ namespace Umbraco.Web.Cache
dc.Refresh(new Guid(DistributedCache.MacroCacheRefresherId), macroId);
}
/// <summary>
/// Refreshes the cache amongst servers for a macro item
/// </summary>
/// <param name="dc"></param>
/// <param name="macro"></param>
public static void RefreshMacroCache(this DistributedCache dc, global::umbraco.cms.businesslogic.macro.Macro macro)
{
if (macro != null)
{
dc.Refresh(new Guid(DistributedCache.MacroCacheRefresherId), macro1 => macro1.Id, macro);
}
}
/// <summary>
/// Removes the cache amongst servers for a macro item
/// </summary>
@@ -168,5 +182,31 @@ namespace Umbraco.Web.Cache
{
dc.Remove(new Guid(DistributedCache.MacroCacheRefresherId), macroId);
}
/// <summary>
/// Removes the cache amongst servers for a macro item
/// </summary>
/// <param name="dc"></param>
/// <param name="macro"></param>
public static void RemoveMacroCache(this DistributedCache dc, macro macro)
{
if (macro != null && macro.Model != null)
{
dc.Remove(new Guid(DistributedCache.MacroCacheRefresherId), macro1 => macro1.Model.Id, macro);
}
}
/// <summary>
/// Removes the cache amongst servers for a macro item
/// </summary>
/// <param name="dc"></param>
/// <param name="macro"></param>
public static void RemoveMacroCache(this DistributedCache dc, global::umbraco.cms.businesslogic.macro.Macro macro)
{
if (macro != null)
{
dc.Remove(new Guid(DistributedCache.MacroCacheRefresherId), macro1 => macro1.Id, macro);
}
}
}
}

View File

@@ -1,4 +1,6 @@
using System;
using Umbraco.Core;
using Umbraco.Core.Cache;
using umbraco;
using umbraco.interfaces;
@@ -7,8 +9,13 @@ namespace Umbraco.Web.Cache
/// <summary>
/// Used to invalidate/refresh the cache for macros
/// </summary>
public class MacroCacheRefresher : ICacheRefresher
public class MacroCacheRefresher : ICacheRefresher<macro>
{
internal static string[] GetCacheKeys(string alias)
{
return new[] { CacheKeys.MacroRuntimeCacheKey + alias, CacheKeys.UmbracoMacroCacheKey + alias };
}
public string Name
{
get
@@ -35,13 +42,32 @@ namespace Umbraco.Web.Cache
void ICacheRefresher.Refresh(int id)
{
macro.GetMacro(id).removeFromCache();
if (id <= 0) return;
var m = new macro(id);
Remove(m);
}
void ICacheRefresher.Remove(int id)
{
macro.GetMacro(id).removeFromCache();
if (id <= 0) return;
var m = new macro(id);
Remove(m);
}
public void Refresh(macro instance)
{
Remove(instance);
}
public void Remove(macro instance)
{
if (instance != null && instance.Model != null && instance.Model.Id > 0)
{
GetCacheKeys(instance.Model.Alias).ForEach(
alias =>
ApplicationContext.Current.ApplicationCache.ClearCacheItem(alias));
}
}
}
}

View File

@@ -1,13 +1,12 @@
using System;
using Umbraco.Core;
using Umbraco.Core.Cache;
using umbraco.interfaces;
namespace Umbraco.Web.Cache
{
public class MediaCacheRefresher : ICacheRefresher
{
const string getmediaCacheKey = "GetMedia";
public Guid UniqueIdentifier
{
get { return new Guid(DistributedCache.MediaCacheRefresherId); }
@@ -44,12 +43,12 @@ namespace Umbraco.Web.Cache
foreach (var idPart in m.Path.Split(','))
{
ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(
string.Format("UL_{0}_{1}_True", getmediaCacheKey, idPart));
string.Format("UL_{0}_{1}_True", CacheKeys.GetMediaCacheKey, idPart));
// Also clear calls that only query this specific item!
if (idPart == m.Id.ToString())
ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(
string.Format("UL_{0}_{1}", getmediaCacheKey, id));
string.Format("UL_{0}_{1}", CacheKeys.GetMediaCacheKey, id));
}
}

View File

@@ -1,5 +1,6 @@
using System;
using Umbraco.Core;
using Umbraco.Core.Cache;
using umbraco.interfaces;
namespace Umbraco.Web.Cache
@@ -38,10 +39,8 @@ namespace Umbraco.Web.Cache
private void ClearCache(int id)
{
const string getmemberCacheKey = "GetMember";
ApplicationContext.Current.ApplicationCache.
ClearCacheByKeySearch(string.Format("UL_{0}_{1}", getmemberCacheKey, id));
ClearCacheByKeySearch(string.Format("UL_{0}_{1}", CacheKeys.GetMemberCacheKey, id));
}
}

View File

@@ -1,4 +1,5 @@
using System;
using Umbraco.Core.Cache;
using Umbraco.Core.Models;
using Umbraco.Core.Sync;
using umbraco;

View File

@@ -1,5 +1,6 @@
using System;
using Umbraco.Core;
using Umbraco.Core.Cache;
using umbraco;
using umbraco.interfaces;
@@ -7,8 +8,7 @@ namespace Umbraco.Web.Cache
{
public class TemplateCacheRefresher : ICacheRefresher
{
private const string TemplateCacheKey = "template";
public string Name
{
get
@@ -46,7 +46,7 @@ namespace Umbraco.Web.Cache
private void RemoveFromCache(int id)
{
ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(
string.Format("{0}{1}", TemplateCacheKey, id));
string.Format("{0}{1}", CacheKeys.TemplateCacheKey, id));
}
}

View File

@@ -1,5 +1,6 @@
using System;
using Umbraco.Core;
using Umbraco.Core.Cache;
using umbraco.interfaces;
namespace Umbraco.Web.Cache
@@ -20,7 +21,7 @@ namespace Umbraco.Web.Cache
public void RefreshAll()
{
ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch("UmbracoUser");
ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(CacheKeys.UserCacheKey);
}
public void Refresh(int id)
@@ -30,7 +31,7 @@ namespace Umbraco.Web.Cache
public void Remove(int id)
{
ApplicationContext.Current.ApplicationCache.ClearCacheItem(string.Format("UmbracoUser{0}", id.ToString()));
ApplicationContext.Current.ApplicationCache.ClearCacheItem(string.Format("{0}{1}", CacheKeys.UserCacheKey, id.ToString()));
}
public void Refresh(Guid id)

View File

@@ -20,6 +20,7 @@ using Umbraco.Core.Events;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Web;
using Umbraco.Web.Cache;
using Umbraco.Web.Macros;
using Umbraco.Web.Templates;
using umbraco.BusinessLogic;
@@ -50,9 +51,6 @@ namespace umbraco
private readonly StringBuilder mContent = new StringBuilder();
private readonly Cache macroCache = HttpRuntime.Cache;
private static readonly object macroRuntimeCacheSyncLock = new object();
private static readonly string macroRuntimeCacheKey = "UmbracoRuntimeMacroCache";
private readonly string macrosAddedKey = "macrosAdded";
public IList<Exception> Exceptions = new List<Exception>();
@@ -141,78 +139,31 @@ namespace umbraco
public macro(int id)
{
Macro m = Macro.GetById(id);
Model = new MacroModel(m);
if (m != null)
{
Model = new MacroModel(m);
}
}
public macro(string alias)
{
Macro m = Macro.GetByAlias(alias);
Model = new MacroModel(m);
if (m != null)
{
Model = new MacroModel(m);
}
}
public MacroModel Model { get; set; }
public static macro GetMacro(string alias)
{
// FlorisRobbemont: issue #27610 -> Presentation macro not supposed to be cached.
return new macro(alias);
//return cms.businesslogic.cache.Cache.GetCacheItem(GetCacheKey(alias), macroRuntimeCacheSyncLock,
// TimeSpan.FromMinutes(60),
// delegate
// {
// try
// {
// return new macro(alias);
// }
// catch
// {
// return null;
// }
// });
}
public static macro GetMacro(int id)
{
// FlorisRobbemont: issue #27610 -> Presentation macro not supposed to be cached.
{
return new macro(id);
//return cms.businesslogic.cache.Cache.GetCacheItem(GetCacheKey(string.Format("by_id_{0}", id)), macroRuntimeCacheSyncLock,
// TimeSpan.FromMinutes(60),
// delegate
// {
// try
// {
// return new macro(id);
// }
// catch
// {
// return null;
// }
// });
}
#endregion
@@ -241,22 +192,16 @@ namespace umbraco
return Model.Name;
}
private static string GetCacheKey(string alias)
{
return macroRuntimeCacheKey + alias;
}
/// <summary>
/// Deletes macro definition from cache.
/// </summary>
/// <returns>True if succesfull, false if nothing has been removed</returns>
//TODO: Update implementation!
[Obsolete("Use DistributedCache.Instance.RemoveMacroCache instead, macro cache will automatically be cleared and shouldn't need to be manually cleared.")]
public bool removeFromCache()
{
if (Model.Id > 0)
{
cms.businesslogic.cache.Cache.ClearCacheItem(GetCacheKey(Model.Alias));
}
DistributedCache.Instance.RemoveMacroCache(this);
//this always returned false... hrm. oh well i guess we leave it like that
return false;
}
@@ -921,12 +866,13 @@ namespace umbraco
// would not be refreshed when the .config file is modified. An application
// restart would be required. Better use the cache and add a dependency.
// SD: Not sure what is meant by the above statement? Having these in a static variable would be preferred!
// SD: The only reason the above statement might be true is because the xslt extension .config file is not a
// real config file!! if it was, we wouldn't have this issue. Having these in a static variable would be preferred!
// If you modify a config file, the app restarts and thus all static variables are reset.
// Having this stuff in cache just adds to the gigantic amount of cache data and will cause more cache turnover to happen.
return cms.businesslogic.cache.Cache.GetCacheItem(
_xsltExtensionsCacheKey, _xsltExtensionsSyncLock,
return ApplicationContext.Current.ApplicationCache.GetCacheItem(
_xsltExtensionsCacheKey,
CacheItemPriority.NotRemovable, // NH 4.7.1, Changing to NotRemovable
null, // no refresh action
_xsltExtensionsDependency(), // depends on the .config file

View File

@@ -61,8 +61,6 @@ namespace umbraco
public bool Delete()
{
// Clear cache!
macro.GetMacro(ParentID).removeFromCache();
new cms.businesslogic.macro.Macro(ParentID).Delete();
return true;
}

View File

@@ -437,9 +437,7 @@ namespace umbraco.presentation.developer.packages
{
Macro s = new Macro(nId);
if (s != null && !String.IsNullOrEmpty(s.Name))
{
// remove from cache
runtimeMacro.GetMacro(s.Id).removeFromCache();
{
s.Delete();
}

View File

@@ -5,6 +5,8 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Runtime.CompilerServices;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using umbraco.cms.businesslogic.cache;
@@ -28,7 +30,7 @@ namespace umbraco.cms.businesslogic.macro
public class Macro
{
private static readonly object macroCacheSyncLock = new object();
private static readonly string umbracoMacroCacheKey = "UmbracoMacroCache";
//private static readonly string umbracoMacroCacheKey = "UmbracoMacroCache";
int _id;
bool _useInEditor;
@@ -279,11 +281,9 @@ namespace umbraco.cms.businesslogic.macro
public virtual void Save()
{
//event
SaveEventArgs e = new SaveEventArgs();
var e = new SaveEventArgs();
FireBeforeSave(e);
InvalidateCache();
if (!e.Cancel) {
FireAfterSave(e);
}
@@ -496,41 +496,42 @@ namespace umbraco.cms.businesslogic.macro
/// <summary>
/// Static contructor for retrieving a macro given an alias
/// </summary>
/// <param name="Alias">The alias of the macro</param>
/// <param name="alias">The alias of the macro</param>
/// <returns>If the macro with the given alias exists, it returns the macro, else null</returns>
public static Macro GetByAlias(string alias)
{
return Cache.GetCacheItem(GetCacheKey(alias), macroCacheSyncLock,
TimeSpan.FromMinutes(30),
delegate
{
try
{
return new Macro(alias);
}
catch
{
return null;
}
});
}
{
return ApplicationContext.Current.ApplicationCache.GetCacheItem(
GetCacheKey(alias),
TimeSpan.FromMinutes(30),
delegate
{
try
{
return new Macro(alias);
}
catch
{
return null;
}
});
}
public static Macro GetById(int id)
{
return Cache.GetCacheItem(GetCacheKey(string.Format("macro_via_id_{0}", id)), macroCacheSyncLock,
TimeSpan.FromMinutes(30),
delegate
{
try
{
return new Macro(id);
}
catch
{
return null;
}
});
return ApplicationContext.Current.ApplicationCache.GetCacheItem(
GetCacheKey(string.Format("macro_via_id_{0}", id)),
TimeSpan.FromMinutes(30),
delegate
{
try
{
return new Macro(id);
}
catch
{
return null;
}
});
}
public static MacroTypes FindMacroType(string xslt, string scriptFile, string scriptType, string scriptAssembly)
@@ -578,18 +579,12 @@ namespace umbraco.cms.businesslogic.macro
}
#region Macro Refactor
private void InvalidateCache()
{
Cache.ClearCacheItem(GetCacheKey(this.Alias));
}
private static string GetCacheKey(string alias)
{
return umbracoMacroCacheKey + alias;
return CacheKeys.UmbracoMacroCacheKey + alias;
}
#endregion