Fixes: #U4-1986 - data type cache is not refreshed in load balanced environments.

This commit is contained in:
Shannon Deminick
2013-03-22 05:04:32 +06:00
parent 2a9309ea38
commit e8dd56786b
9 changed files with 116 additions and 46 deletions

View File

@@ -35,5 +35,7 @@ namespace Umbraco.Core.Cache
public const string StylesheetCacheKey = "UmbracoStylesheet";
public const string StylesheetPropertyCacheKey = "UmbracoStylesheetProperty";
public const string DataTypeCacheKey = "UmbracoDataTypeDefinition";
}
}

View File

@@ -22,6 +22,15 @@ namespace Umbraco.Web.Cache
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
//Bind to data type events
//NOTE: we need to bind to legacy and new API events currently: http://issues.umbraco.org/issue/U4-1979
global::umbraco.cms.businesslogic.datatype.DataTypeDefinition.Deleting += DataTypeDefinitionDeleting;
global::umbraco.cms.businesslogic.datatype.DataTypeDefinition.Saving += DataTypeDefinitionSaving;
DataTypeService.Deleted += DataTypeServiceDeleted;
DataTypeService.Saved += DataTypeServiceSaved;
//Bind to stylesheet events
//NOTE: we need to bind to legacy and new API events currently: http://issues.umbraco.org/issue/U4-1979
@@ -88,6 +97,28 @@ namespace Umbraco.Web.Cache
MediaService.Trashing += MediaServiceTrashing;
}
#region DataType event handlers
static void DataTypeServiceSaved(IDataTypeService sender, Core.Events.SaveEventArgs<IDataTypeDefinition> e)
{
e.SavedEntities.ForEach(x => DistributedCache.Instance.RefreshDataTypeCache(x.Id));
}
static void DataTypeServiceDeleted(IDataTypeService sender, Core.Events.DeleteEventArgs<IDataTypeDefinition> e)
{
e.DeletedEntities.ForEach(x => DistributedCache.Instance.RemoveDataTypeCache(x.Id));
}
static void DataTypeDefinitionSaving(global::umbraco.cms.businesslogic.datatype.DataTypeDefinition sender, System.EventArgs e)
{
DistributedCache.Instance.RefreshDataTypeCache(sender.Id);
}
static void DataTypeDefinitionDeleting(global::umbraco.cms.businesslogic.datatype.DataTypeDefinition sender, System.EventArgs e)
{
DistributedCache.Instance.RemoveDataTypeCache(sender.Id);
}
#endregion
#region Stylesheet and stylesheet property event handlers
static void StylesheetPropertyAfterSave(global::umbraco.cms.businesslogic.web.StylesheetProperty sender, SaveEventArgs e)
{

View File

@@ -0,0 +1,46 @@
using System;
using Umbraco.Core;
using Umbraco.Core.Cache;
namespace Umbraco.Web.Cache
{
/// <summary>
/// A cache refresher to ensure member cache is updated when members change
/// </summary>
public sealed class DataTypeCacheRefresher : CacheRefresherBase<DataTypeCacheRefresher>
{
protected override DataTypeCacheRefresher Instance
{
get { return this; }
}
public override Guid UniqueIdentifier
{
get { return new Guid(DistributedCache.DataTypeCacheRefresherId); }
}
public override string Name
{
get { return "Clears data type cache"; }
}
public override void Refresh(int id)
{
ClearCache(id);
base.Refresh(id);
}
public override void Remove(int id)
{
ClearCache(id);
base.Remove(id);
}
private void ClearCache(int id)
{
ApplicationContext.Current.ApplicationCache.
ClearCacheByKeySearch(string.Format("{0}{1}", CacheKeys.DataTypeCacheKey, id));
}
}
}

View File

@@ -46,6 +46,7 @@ namespace Umbraco.Web.Cache
public const string DomainCacheRefresherId = "11290A79-4B57-4C99-AD72-7748A3CF38AF";
public const string StylesheetCacheRefresherId = "E0633648-0DEB-44AE-9A48-75C3A55CB670";
public const string StylesheetPropertyCacheRefresherId = "2BC7A3A4-6EB1-4FBC-BAA3-C9E7B6D36D38";
public const string DataTypeCacheRefresherId = "35B16C25-A17E-45D7-BC8F-EDAB1DCC28D2";
#endregion

View File

@@ -48,6 +48,29 @@ namespace Umbraco.Web.Cache
#endregion
#region Data type cache
/// <summary>
/// Refreshes the cache amongst servers for a template
/// </summary>
/// <param name="dc"></param>
/// <param name="dataTypeId"></param>
public static void RefreshDataTypeCache(this DistributedCache dc, int dataTypeId)
{
dc.Refresh(new Guid(DistributedCache.DataTypeCacheRefresherId), dataTypeId);
}
/// <summary>
/// Removes the cache amongst servers for a template
/// </summary>
/// <param name="dc"></param>
/// <param name="dataTypeId"></param>
public static void RemoveDataTypeCache(this DistributedCache dc, int dataTypeId)
{
dc.Remove(new Guid(DistributedCache.DataTypeCacheRefresherId), dataTypeId);
}
#endregion
#region Page cache
/// <summary>
/// Refreshes the cache amongst servers for all pages

View File

@@ -27,7 +27,7 @@ namespace Umbraco.Web.Cache
public override string Name
{
get { return "Clears Member Cache from umbraco.library"; }
get { return "Clears Member Cache"; }
}
public override void Refresh(int id)

View File

@@ -264,6 +264,7 @@
<Compile Include="ApplicationContextExtensions.cs" />
<Compile Include="CacheHelperExtensions.cs" />
<Compile Include="Cache\ContentTypeCacheRefresher.cs" />
<Compile Include="Cache\DataTypeCacheRefresher.cs" />
<Compile Include="Cache\DistributedCache.cs" />
<Compile Include="Cache\DistributedCacheExtensions.cs" />
<Compile Include="Cache\CacheRefresherEventHandler.cs" />

View File

@@ -3,6 +3,7 @@ using System.Data;
using System.Collections;
using System.Linq;
using Umbraco.Core.Cache;
using umbraco.DataLayer;
using System.Xml;
using umbraco.interfaces;
@@ -101,7 +102,7 @@ namespace umbraco.cms.businesslogic.datatype
SqlHelper.ExecuteNonQuery("delete from cmsDataType where nodeId=@nodeId", SqlHelper.CreateParameter("@nodeId", this.Id));
base.delete();
cache.Cache.ClearCacheItem(string.Format("UmbracoDataTypeDefinition{0}", Id));
OnDeleting(new EventArgs());
}
[Obsolete("Use the standard delete() method instead")]
@@ -118,22 +119,6 @@ namespace umbraco.cms.businesslogic.datatype
OnSaving(EventArgs.Empty);
}
/*
public SortedList PreValues {
get {
SortedList retVal = new SortedList();
SqlDataReader dr = SqlHelper.ExecuteReader("select id, value from cmsDataTypePreValues where dataTypeNodeId = @nodeId order by sortOrder", SqlHelper.CreateParameter("@nodeId", this.Id));
while (dr.Read())
{
retVal.Add(dr.GetString("id"), dr.GetString("value"));
}
dr.Close();
return retVal;
}
}
*/
public XmlElement ToXml(XmlDocument xd)
{
XmlElement dt = xd.CreateElement("DataType");
@@ -171,12 +156,12 @@ namespace umbraco.cms.businesslogic.datatype
)
{
BusinessLogic.User u = umbraco.BusinessLogic.User.GetCurrent();
BusinessLogic.User u = BusinessLogic.User.GetCurrent();
if (u == null)
u = BusinessLogic.User.GetUser(0);
cms.businesslogic.datatype.controls.Factory f = new umbraco.cms.businesslogic.datatype.controls.Factory();
var f = new controls.Factory();
DataTypeDefinition dtd = MakeNew(u, _name, new Guid(_def));
@@ -309,23 +294,17 @@ namespace umbraco.cms.businesslogic.datatype
public static DataTypeDefinition GetDataTypeDefinition(int id)
{
if (System.Web.HttpRuntime.Cache[string.Format("UmbracoDataTypeDefinition{0}", id.ToString())] == null)
{
DataTypeDefinition dt = new DataTypeDefinition(id);
System.Web.HttpRuntime.Cache.Insert(string.Format("UmbracoDataTypeDefinition{0}", id.ToString()), dt);
}
return (DataTypeDefinition)System.Web.HttpRuntime.Cache[string.Format("UmbracoDataTypeDefinition{0}", id.ToString())];
return ApplicationContext.Current.ApplicationCache.GetCacheItem(
string.Format("{0}{1}", CacheKeys.DataTypeCacheKey, id),
() => new DataTypeDefinition(id));
}
[Obsolete("Use GetDataTypeDefinition(int id) instead", false)]
public static DataTypeDefinition GetDataTypeDefinition(Guid id)
{
if (System.Web.HttpRuntime.Cache[string.Format("UmbracoDataTypeDefinition{0}", id.ToString())] == null)
{
DataTypeDefinition dt = new DataTypeDefinition(id);
System.Web.HttpRuntime.Cache.Insert(string.Format("UmbracoDataTypeDefinition{0}", id.ToString()), dt);
}
return (DataTypeDefinition)System.Web.HttpRuntime.Cache[string.Format("UmbracoDataTypeDefinition{0}", id.ToString())];
return ApplicationContext.Current.ApplicationCache.GetCacheItem(
string.Format("{0}{1}", CacheKeys.DataTypeCacheKey, id),
() => new DataTypeDefinition(id));
}
#endregion
@@ -355,7 +334,7 @@ namespace umbraco.cms.businesslogic.datatype
public delegate void DeleteEventHandler(DataTypeDefinition sender, EventArgs e);
/// <summary>
/// Occurs when a macro is saved.
/// Occurs when a data type is saved.
/// </summary>
public static event SaveEventHandler Saving;
protected virtual void OnSaving(EventArgs e)

View File

@@ -166,18 +166,5 @@ namespace umbraco.cms.businesslogic.relation
#endregion
/// <summary>
/// Occurs when [after delete].
/// </summary>
public static event EventHandler<DeleteEventArgs> AfterDelete;
/// <summary>
/// Raises the <see cref="AfterDelete"/> event.
/// </summary>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void FireAfterDelete(DeleteEventArgs e)
{
if (AfterDelete != null)
AfterDelete(this, e);
}
}
}