using System; using System.Collections.Generic; using System.Linq; using Umbraco.Core; using Umbraco.Core.Sync; using Umbraco.Core.Cache; 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 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 refresherGuid, Func getNumericId, params T[] instances) { if (refresherGuid == Guid.Empty || instances.Length == 0 || getNumericId == null) return; ServerMessengerResolver.Current.Messenger.PerformRefresh( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(refresherGuid), 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 refresherGuid, int id) { if (refresherGuid == Guid.Empty || id == default(int)) return; ServerMessengerResolver.Current.Messenger.PerformRefresh( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(refresherGuid), 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 refresherGuid, Guid id) { if (refresherGuid == Guid.Empty || id == Guid.Empty) return; ServerMessengerResolver.Current.Messenger.PerformRefresh( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(refresherGuid), id); } // payload should be an object, or array of objects, NOT a // Linq enumerable of some sort (IEnumerable, query...) public void RefreshByPayload(Guid refresherGuid, TPayload[] payload) { if (refresherGuid == Guid.Empty || payload == null) return; ServerMessengerResolver.Current.Messenger.PerformRefresh( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(refresherGuid), payload); } // so deal with IEnumerable public void RefreshByPayload(Guid refresherGuid, IEnumerable payloads) where TPayload : class { if (refresherGuid == Guid.Empty || payloads == null) return; ServerMessengerResolver.Current.Messenger.PerformRefresh( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(refresherGuid), payloads.ToArray()); } /// /// Notifies the distributed cache, for a specified . /// /// The unique identifier of the ICacheRefresher. /// The notification content. public void RefreshByJson(Guid refresherGuid, string jsonPayload) { if (refresherGuid == Guid.Empty || jsonPayload.IsNullOrWhiteSpace()) return; ServerMessengerResolver.Current.Messenger.PerformRefresh( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(refresherGuid), 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 refresherGuid) { if (refresherGuid == Guid.Empty) return; ServerMessengerResolver.Current.Messenger.PerformRefreshAll( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(refresherGuid)); } /// /// 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 refresherGuid, int id) { if (refresherGuid == Guid.Empty || id == default(int)) return; ServerMessengerResolver.Current.Messenger.PerformRemove( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(refresherGuid), 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 refresherGuid, Func getNumericId, params T[] instances) { ServerMessengerResolver.Current.Messenger.PerformRemove( ServerRegistrarResolver.Current.Registrar.Registrations, GetRefresherById(refresherGuid), getNumericId, instances); } #endregion // helper method to get an ICacheRefresher by its unique identifier private static ICacheRefresher GetRefresherById(Guid refresherGuid) { return CacheRefreshersResolver.Current.GetById(refresherGuid); } } }