using System; using System.ComponentModel; using System.Linq; using Umbraco.Core; using Umbraco.Core.Sync; using umbraco.interfaces; namespace Umbraco.Web.Cache { /// /// Represents the entry point into Umbraco's distributed cache infrastructure. /// /// /// /// The distributed cache infrastructure ensures that distributed caches are /// invalidated properly in load balancing environments. /// /// /// Distribute caches include static (in-memory) cache, runtime cache, front-end content cache, Examine/Lucene indexes /// /// public sealed class DistributedCache { #region Public constants/Ids public const string ApplicationTreeCacheRefresherId = "0AC6C028-9860-4EA4-958D-14D39F45886E"; public const string ApplicationCacheRefresherId = "B15F34A1-BC1D-4F8B-8369-3222728AB4C8"; public const string TemplateRefresherId = "DD12B6A0-14B9-46e8-8800-C154F74047C8"; public const string PageCacheRefresherId = "27AB3022-3DFA-47b6-9119-5945BC88FD66"; public const string UnpublishedPageCacheRefresherId = "55698352-DFC5-4DBE-96BD-A4A0F6F77145"; public const string MemberCacheRefresherId = "E285DF34-ACDC-4226-AE32-C0CB5CF388DA"; public const string MemberGroupCacheRefresherId = "187F236B-BD21-4C85-8A7C-29FBA3D6C00C"; public const string MediaCacheRefresherId = "B29286DD-2D40-4DDB-B325-681226589FEC"; public const string MacroCacheRefresherId = "7B1E683C-5F34-43dd-803D-9699EA1E98CA"; public const string UserCacheRefresherId = "E057AF6D-2EE6-41F4-8045-3694010F0AA6"; public const string UserPermissionsCacheRefresherId = "840AB9C5-5C0B-48DB-A77E-29FE4B80CD3A"; public const string UserTypeCacheRefresherId = "7E707E21-0195-4522-9A3C-658CC1761BD4"; public const string ContentTypeCacheRefresherId = "6902E22C-9C10-483C-91F3-66B7CAE9E2F5"; public const string LanguageCacheRefresherId = "3E0F95D8-0BE5-44B8-8394-2B8750B62654"; 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"; public const string DictionaryCacheRefresherId = "D1D7E227-F817-4816-BFE9-6C39B6152884"; public const string PublicAccessCacheRefresherId = "1DB08769-B104-4F8B-850E-169CAC1DF2EC"; 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); #endregion #region Constructor & Singleton // note - should inject into the application instead of using a singleton private static readonly DistributedCache InstanceObject = new DistributedCache(); /// /// Initializes a new instance of the class. /// private DistributedCache() { } /// /// Gets the static unique instance of the class. /// /// The static unique instance of the class. /// Exists so that extension methods can be added to the distributed cache. public static DistributedCache Instance { get { return InstanceObject; } } #endregion #region Core notification methods /// /// Notifies the distributed cache of specifieds item invalidation, for a specified . /// /// The type of the invalidated items. /// The unique identifier of the ICacheRefresher. /// A function returning the unique identifier of items. /// The invalidated items. /// /// This method is much better for performance because it does not need to re-lookup object instances. /// public void Refresh(Guid factoryGuid, Func getNumericId, params T[] instances) { if (factoryGuid == Guid.Empty || instances.Length == 0 || getNumericId == null) return; ServerMessengerResolver.Current.Messenger.PerformRefresh( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(factoryGuid), getNumericId, instances); } /// /// Notifies the distributed cache of a specified item invalidation, for a specified . /// /// The unique identifier of the ICacheRefresher. /// The unique identifier of the invalidated item. public void Refresh(Guid factoryGuid, int id) { if (factoryGuid == Guid.Empty || id == default(int)) return; ServerMessengerResolver.Current.Messenger.PerformRefresh( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(factoryGuid), id); } /// /// Notifies the distributed cache of a specified item invalidation, for a specified . /// /// The unique identifier of the ICacheRefresher. /// The unique identifier of the invalidated item. public void Refresh(Guid factoryGuid, Guid id) { if (factoryGuid == Guid.Empty || id == Guid.Empty) return; ServerMessengerResolver.Current.Messenger.PerformRefresh( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(factoryGuid), id); } 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); } /// /// Notifies the distributed cache, for a specified . /// /// The unique identifier of the ICacheRefresher. /// The notification content. public void RefreshByJson(Guid factoryGuid, string jsonPayload) { if (factoryGuid == Guid.Empty || jsonPayload.IsNullOrWhiteSpace()) return; ServerMessengerResolver.Current.Messenger.PerformRefresh( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(factoryGuid), jsonPayload); } ///// ///// Notifies the distributed cache, for a specified . ///// ///// The unique identifier of the ICacheRefresher. ///// The notification content. //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); //} /// /// Notifies the distributed cache of a global invalidation for a specified . /// /// The unique identifier of the ICacheRefresher. public void RefreshAll(Guid factoryGuid) { if (factoryGuid == Guid.Empty) return; ServerMessengerResolver.Current.Messenger.PerformRefreshAll( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(factoryGuid)); } [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!")] public void RefreshAll(Guid factoryGuid, bool allServers) { if (factoryGuid == Guid.Empty) return; if (allServers) { RefreshAll(factoryGuid); } else { ServerMessengerResolver.Current.Messenger.PerformRefreshAll( Enumerable.Empty(), GetRefresherById(factoryGuid)); } } /// /// Notifies the distributed cache of a specified item removal, for a specified . /// /// The unique identifier of the ICacheRefresher. /// The unique identifier of the removed item. public void Remove(Guid factoryGuid, int id) { if (factoryGuid == Guid.Empty || id == default(int)) return; ServerMessengerResolver.Current.Messenger.PerformRemove( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(factoryGuid), id); } /// /// Notifies the distributed cache of specifieds item removal, for a specified . /// /// The type of the removed items. /// The unique identifier of the ICacheRefresher. /// A function returning the unique identifier of items. /// The removed items. /// /// This method is much better for performance because it does not need to re-lookup object instances. /// public void Remove(Guid factoryGuid, Func getNumericId, params T[] instances) { ServerMessengerResolver.Current.Messenger.PerformRemove( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(factoryGuid), getNumericId, instances); } #endregion // helper method to get an ICacheRefresher by its unique identifier private static ICacheRefresher GetRefresherById(Guid uniqueIdentifier) { return CacheRefreshersResolver.Current.GetById(uniqueIdentifier); } } }