2013-02-07 03:22:38 +06:00
using System ;
2015-10-27 19:24:56 +01:00
using System.ComponentModel ;
2013-03-16 01:37:05 +06:00
using System.Linq ;
2013-02-07 03:22:38 +06:00
using Umbraco.Core ;
2013-02-11 20:07:23 +06:00
using Umbraco.Core.Sync ;
2013-02-07 04:26:48 +06:00
using umbraco.interfaces ;
2013-02-07 03:22:38 +06:00
namespace Umbraco.Web.Cache
{
/// <summary>
2015-03-04 12:16:28 +01:00
/// Represents the entry point into Umbraco's distributed cache infrastructure.
2013-02-07 03:22:38 +06:00
/// </summary>
/// <remarks>
2015-03-27 12:37:03 +11:00
/// <para>
/// The distributed cache infrastructure ensures that distributed caches are
/// invalidated properly in load balancing environments.
/// </para>
/// <para>
/// Distribute caches include static (in-memory) cache, runtime cache, front-end content cache, Examine/Lucene indexes
/// </para>
2013-02-07 03:22:38 +06:00
/// </remarks>
2013-03-16 09:03:26 +06:00
public sealed class DistributedCache
2013-02-07 03:22:38 +06:00
{
2013-02-07 03:49:45 +06:00
#region Public constants / Ids
2013-04-04 21:57:41 +06:00
public const string ApplicationTreeCacheRefresherId = "0AC6C028-9860-4EA4-958D-14D39F45886E" ;
public const string ApplicationCacheRefresherId = "B15F34A1-BC1D-4F8B-8369-3222728AB4C8" ;
2013-02-07 03:55:14 +06:00
public const string TemplateRefresherId = "DD12B6A0-14B9-46e8-8800-C154F74047C8" ;
public const string PageCacheRefresherId = "27AB3022-3DFA-47b6-9119-5945BC88FD66" ;
2014-03-06 17:50:08 +11:00
public const string UnpublishedPageCacheRefresherId = "55698352-DFC5-4DBE-96BD-A4A0F6F77145" ;
2013-02-07 03:58:47 +06:00
public const string MemberCacheRefresherId = "E285DF34-ACDC-4226-AE32-C0CB5CF388DA" ;
2014-02-12 17:14:16 +11:00
public const string MemberGroupCacheRefresherId = "187F236B-BD21-4C85-8A7C-29FBA3D6C00C" ;
2013-02-07 04:01:50 +06:00
public const string MediaCacheRefresherId = "B29286DD-2D40-4DDB-B325-681226589FEC" ;
2013-02-07 04:04:51 +06:00
public const string MacroCacheRefresherId = "7B1E683C-5F34-43dd-803D-9699EA1E98CA" ;
2013-02-12 04:13:29 +06:00
public const string UserCacheRefresherId = "E057AF6D-2EE6-41F4-8045-3694010F0AA6" ;
2013-07-09 11:47:46 +10:00
public const string UserPermissionsCacheRefresherId = "840AB9C5-5C0B-48DB-A77E-29FE4B80CD3A" ;
2013-04-04 03:43:05 +06:00
public const string UserTypeCacheRefresherId = "7E707E21-0195-4522-9A3C-658CC1761BD4" ;
2013-03-16 08:47:55 +06:00
public const string ContentTypeCacheRefresherId = "6902E22C-9C10-483C-91F3-66B7CAE9E2F5" ;
2013-03-22 00:35:15 +06:00
public const string LanguageCacheRefresherId = "3E0F95D8-0BE5-44B8-8394-2B8750B62654" ;
2013-03-22 00:49:07 +06:00
public const string DomainCacheRefresherId = "11290A79-4B57-4C99-AD72-7748A3CF38AF" ;
2013-03-22 01:49:34 +06:00
public const string StylesheetCacheRefresherId = "E0633648-0DEB-44AE-9A48-75C3A55CB670" ;
public const string StylesheetPropertyCacheRefresherId = "2BC7A3A4-6EB1-4FBC-BAA3-C9E7B6D36D38" ;
2013-03-22 05:04:32 +06:00
public const string DataTypeCacheRefresherId = "35B16C25-A17E-45D7-BC8F-EDAB1DCC28D2" ;
2013-03-23 01:59:25 +06:00
public const string DictionaryCacheRefresherId = "D1D7E227-F817-4816-BFE9-6C39B6152884" ;
2014-03-27 14:43:07 +11:00
public const string PublicAccessCacheRefresherId = "1DB08769-B104-4F8B-850E-169CAC1DF2EC" ;
2013-03-22 00:49:07 +06:00
2015-03-04 12:16:28 +01:00
public static readonly Guid ApplicationTreeCacheRefresherGuid = new Guid ( ApplicationTreeCacheRefresherId ) ;
public static readonly Guid ApplicationCacheRefresherGuid = new Guid ( ApplicationCacheRefresherId ) ;
public static readonly Guid TemplateRefresherGuid = new Guid ( TemplateRefresherId ) ;
public static readonly Guid PageCacheRefresherGuid = new Guid ( PageCacheRefresherId ) ;
public static readonly Guid UnpublishedPageCacheRefresherGuid = new Guid ( UnpublishedPageCacheRefresherId ) ;
public static readonly Guid MemberCacheRefresherGuid = new Guid ( MemberCacheRefresherId ) ;
public static readonly Guid MemberGroupCacheRefresherGuid = new Guid ( MemberGroupCacheRefresherId ) ;
public static readonly Guid MediaCacheRefresherGuid = new Guid ( MediaCacheRefresherId ) ;
public static readonly Guid MacroCacheRefresherGuid = new Guid ( MacroCacheRefresherId ) ;
public static readonly Guid UserCacheRefresherGuid = new Guid ( UserCacheRefresherId ) ;
public static readonly Guid UserPermissionsCacheRefresherGuid = new Guid ( UserPermissionsCacheRefresherId ) ;
public static readonly Guid UserTypeCacheRefresherGuid = new Guid ( UserTypeCacheRefresherId ) ;
public static readonly Guid ContentTypeCacheRefresherGuid = new Guid ( ContentTypeCacheRefresherId ) ;
public static readonly Guid LanguageCacheRefresherGuid = new Guid ( LanguageCacheRefresherId ) ;
public static readonly Guid DomainCacheRefresherGuid = new Guid ( DomainCacheRefresherId ) ;
public static readonly Guid StylesheetCacheRefresherGuid = new Guid ( StylesheetCacheRefresherId ) ;
public static readonly Guid StylesheetPropertyCacheRefresherGuid = new Guid ( StylesheetPropertyCacheRefresherId ) ;
public static readonly Guid DataTypeCacheRefresherGuid = new Guid ( DataTypeCacheRefresherId ) ;
public static readonly Guid DictionaryCacheRefresherGuid = new Guid ( DictionaryCacheRefresherId ) ;
public static readonly Guid PublicAccessCacheRefresherGuid = new Guid ( PublicAccessCacheRefresherId ) ;
2013-02-07 03:49:45 +06:00
#endregion
2015-03-04 12:16:28 +01:00
#region Constructor & Singleton
// note - should inject into the application instead of using a singleton
2013-02-07 03:29:47 +06:00
private static readonly DistributedCache InstanceObject = new DistributedCache ( ) ;
2013-02-07 03:22:38 +06:00
/// <summary>
2015-03-04 12:16:28 +01:00
/// Initializes a new instance of the <see cref="DistributedCache"/> class.
2013-02-07 03:22:38 +06:00
/// </summary>
2013-02-07 03:29:47 +06:00
private DistributedCache ( )
2015-03-04 12:16:28 +01:00
{ }
2013-02-07 03:22:38 +06:00
/// <summary>
2015-03-04 12:16:28 +01:00
/// Gets the static unique instance of the <see cref="DistributedCache"/> class.
2013-02-07 03:22:38 +06:00
/// </summary>
2015-03-04 12:16:28 +01:00
/// <returns>The static unique instance of the <see cref="DistributedCache"/> class.</returns>
/// <remarks>Exists so that extension methods can be added to the distributed cache.</remarks>
2013-02-07 03:29:47 +06:00
public static DistributedCache Instance
2013-02-07 03:22:38 +06:00
{
get
{
return InstanceObject ;
}
}
2015-03-04 12:16:28 +01:00
#endregion
#region Core notification methods
2013-02-12 04:47:36 +06:00
/// <summary>
2015-03-04 12:16:28 +01:00
/// Notifies the distributed cache of specifieds item invalidation, for a specified <see cref="ICacheRefresher"/>.
2013-02-12 04:47:36 +06:00
/// </summary>
2015-03-04 12:16:28 +01:00
/// <typeparam name="T">The type of the invalidated items.</typeparam>
/// <param name="factoryGuid">The unique identifier of the ICacheRefresher.</param>
/// <param name="getNumericId">A function returning the unique identifier of items.</param>
/// <param name="instances">The invalidated items.</param>
2013-02-12 04:47:36 +06:00
/// <remarks>
2015-03-04 12:16:28 +01:00
/// This method is much better for performance because it does not need to re-lookup object instances.
2013-02-12 04:47:36 +06:00
/// </remarks>
public void Refresh < T > ( Guid factoryGuid , Func < T , int > getNumericId , params T [ ] instances )
{
2014-03-21 17:04:30 +11:00
if ( factoryGuid = = Guid . Empty | | instances . Length = = 0 | | getNumericId = = null ) return ;
2015-03-04 12:16:28 +01:00
ServerMessengerResolver . Current . Messenger . PerformRefresh (
2013-02-12 04:47:36 +06:00
ServerRegistrarResolver . Current . Registrar . Registrations ,
GetRefresherById ( factoryGuid ) ,
getNumericId ,
instances ) ;
}
2013-02-07 03:22:38 +06:00
/// <summary>
2015-03-04 12:16:28 +01:00
/// Notifies the distributed cache of a specified item invalidation, for a specified <see cref="ICacheRefresher"/>.
2013-02-07 03:22:38 +06:00
/// </summary>
2015-03-04 12:16:28 +01:00
/// <param name="factoryGuid">The unique identifier of the ICacheRefresher.</param>
/// <param name="id">The unique identifier of the invalidated item.</param>
2013-02-07 03:22:38 +06:00
public void Refresh ( Guid factoryGuid , int id )
{
2014-03-21 17:04:30 +11:00
if ( factoryGuid = = Guid . Empty | | id = = default ( int ) ) return ;
2013-02-12 03:46:27 +06:00
ServerMessengerResolver . Current . Messenger . PerformRefresh (
ServerRegistrarResolver . Current . Registrar . Registrations ,
GetRefresherById ( factoryGuid ) ,
id ) ;
2013-02-07 03:22:38 +06:00
}
/// <summary>
2015-03-04 12:16:28 +01:00
/// Notifies the distributed cache of a specified item invalidation, for a specified <see cref="ICacheRefresher"/>.
2013-02-07 03:22:38 +06:00
/// </summary>
2015-03-04 12:16:28 +01:00
/// <param name="factoryGuid">The unique identifier of the ICacheRefresher.</param>
/// <param name="id">The unique identifier of the invalidated item.</param>
2013-02-07 03:22:38 +06:00
public void Refresh ( Guid factoryGuid , Guid id )
{
2014-03-21 17:04:30 +11:00
if ( factoryGuid = = Guid . Empty | | id = = Guid . Empty ) return ;
2013-02-12 03:46:27 +06:00
ServerMessengerResolver . Current . Messenger . PerformRefresh (
ServerRegistrarResolver . Current . Registrar . Registrations ,
GetRefresherById ( factoryGuid ) ,
id ) ;
2013-02-07 03:22:38 +06:00
}
2015-04-08 14:21:58 +02:00
public void RefreshByPayload ( Guid factoryGuid , object payload )
{
if ( factoryGuid = = Guid . Empty | | payload = = null ) return ;
ServerMessengerResolver . Current . Messenger . PerformRefresh (
ServerRegistrarResolver . Current . Registrar . Registrations ,
GetRefresherById ( factoryGuid ) ,
payload ) ;
}
2013-03-21 20:30:32 +06:00
/// <summary>
2015-03-04 12:16:28 +01:00
/// Notifies the distributed cache, for a specified <see cref="ICacheRefresher"/>.
2013-03-21 20:30:32 +06:00
/// </summary>
2015-03-04 12:16:28 +01:00
/// <param name="factoryGuid">The unique identifier of the ICacheRefresher.</param>
/// <param name="jsonPayload">The notification content.</param>
2013-03-21 20:30:32 +06:00
public void RefreshByJson ( Guid factoryGuid , string jsonPayload )
{
2014-03-21 17:04:30 +11:00
if ( factoryGuid = = Guid . Empty | | jsonPayload . IsNullOrWhiteSpace ( ) ) return ;
2013-03-21 20:30:32 +06:00
ServerMessengerResolver . Current . Messenger . PerformRefresh (
ServerRegistrarResolver . Current . Registrar . Registrations ,
GetRefresherById ( factoryGuid ) ,
jsonPayload ) ;
}
2015-03-04 12:16:28 +01:00
///// <summary>
///// Notifies the distributed cache, for a specified <see cref="ICacheRefresher"/>.
///// </summary>
///// <param name="refresherId">The unique identifier of the ICacheRefresher.</param>
///// <param name="payload">The notification content.</param>
//internal void Notify(Guid refresherId, object payload)
//{
// if (refresherId == Guid.Empty || payload == null) return;
// ServerMessengerResolver.Current.Messenger.Notify(
// ServerRegistrarResolver.Current.Registrar.Registrations,
// GetRefresherById(refresherId),
// json);
//}
2013-02-07 03:22:38 +06:00
/// <summary>
2015-03-04 12:16:28 +01:00
/// Notifies the distributed cache of a global invalidation for a specified <see cref="ICacheRefresher"/>.
2013-02-07 03:22:38 +06:00
/// </summary>
2015-03-04 12:16:28 +01:00
/// <param name="factoryGuid">The unique identifier of the ICacheRefresher.</param>
2013-02-07 03:22:38 +06:00
public void RefreshAll ( Guid factoryGuid )
2013-03-16 01:37:05 +06:00
{
2014-03-21 17:04:30 +11:00
if ( factoryGuid = = Guid . Empty ) return ;
2015-10-27 19:24:56 +01:00
ServerMessengerResolver . Current . Messenger . PerformRefreshAll (
ServerRegistrarResolver . Current . Registrar . Registrations ,
GetRefresherById ( factoryGuid ) ) ;
2013-03-16 01:37:05 +06:00
}
2015-10-27 19:24:56 +01:00
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This method is no longer in use and does not work as advertised, the allServers parameter doesnt have any affect for database server messengers, do not use!")]
2013-03-16 01:37:05 +06:00
public void RefreshAll ( Guid factoryGuid , bool allServers )
2013-02-07 03:22:38 +06:00
{
2014-03-21 17:04:30 +11:00
if ( factoryGuid = = Guid . Empty ) return ;
2015-10-27 19:24:56 +01:00
if ( allServers )
{
RefreshAll ( factoryGuid ) ;
}
else
{
ServerMessengerResolver . Current . Messenger . PerformRefreshAll (
Enumerable . Empty < IServerAddress > ( ) ,
GetRefresherById ( factoryGuid ) ) ;
}
2013-02-07 03:22:38 +06:00
}
/// <summary>
2015-03-04 12:16:28 +01:00
/// Notifies the distributed cache of a specified item removal, for a specified <see cref="ICacheRefresher"/>.
2013-02-07 03:22:38 +06:00
/// </summary>
2015-03-04 12:16:28 +01:00
/// <param name="factoryGuid">The unique identifier of the ICacheRefresher.</param>
/// <param name="id">The unique identifier of the removed item.</param>
2013-02-07 03:22:38 +06:00
public void Remove ( Guid factoryGuid , int id )
{
2014-03-21 17:04:30 +11:00
if ( factoryGuid = = Guid . Empty | | id = = default ( int ) ) return ;
2013-02-12 03:46:27 +06:00
ServerMessengerResolver . Current . Messenger . PerformRemove (
ServerRegistrarResolver . Current . Registrar . Registrations ,
GetRefresherById ( factoryGuid ) ,
id ) ;
2013-02-07 03:22:38 +06:00
}
2015-03-04 12:16:28 +01:00
2013-02-12 07:35:47 +06:00
/// <summary>
2015-03-04 12:16:28 +01:00
/// Notifies the distributed cache of specifieds item removal, for a specified <see cref="ICacheRefresher"/>.
2013-02-12 07:35:47 +06:00
/// </summary>
2015-03-04 12:16:28 +01:00
/// <typeparam name="T">The type of the removed items.</typeparam>
/// <param name="factoryGuid">The unique identifier of the ICacheRefresher.</param>
/// <param name="getNumericId">A function returning the unique identifier of items.</param>
/// <param name="instances">The removed items.</param>
/// <remarks>
/// This method is much better for performance because it does not need to re-lookup object instances.
/// </remarks>
2013-02-12 07:35:47 +06:00
public void Remove < T > ( Guid factoryGuid , Func < T , int > getNumericId , params T [ ] instances )
{
2015-03-04 12:16:28 +01:00
ServerMessengerResolver . Current . Messenger . PerformRemove (
2013-02-12 07:35:47 +06:00
ServerRegistrarResolver . Current . Registrar . Registrations ,
GetRefresherById ( factoryGuid ) ,
getNumericId ,
instances ) ;
2015-03-04 12:16:28 +01:00
}
2013-03-21 20:30:32 +06:00
2015-03-04 12:16:28 +01:00
#endregion
// helper method to get an ICacheRefresher by its unique identifier
2013-02-07 04:26:48 +06:00
private static ICacheRefresher GetRefresherById ( Guid uniqueIdentifier )
{
return CacheRefreshersResolver . Current . GetById ( uniqueIdentifier ) ;
2013-02-07 03:22:38 +06:00
}
}
2014-03-25 20:37:20 -07:00
}