2013-02-07 03:22:38 +06:00
|
|
|
using System;
|
2016-05-26 17:12:04 +02:00
|
|
|
using System.Collections.Generic;
|
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;
|
2016-03-17 15:59:35 +01:00
|
|
|
using Umbraco.Core.Cache;
|
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
|
|
|
{
|
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
|
|
|
{ }
|
2016-05-26 17:12:04 +02: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
|
|
|
|
|
{
|
2016-05-26 17:12:04 +02:00
|
|
|
return InstanceObject;
|
2013-02-07 03:22:38 +06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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>
|
2016-05-26 17:12:04 +02:00
|
|
|
/// <param name="refresherGuid">The unique identifier of the ICacheRefresher.</param>
|
2015-03-04 12:16:28 +01:00
|
|
|
/// <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>
|
2016-05-26 17:12:04 +02:00
|
|
|
public void Refresh<T>(Guid refresherGuid, Func<T, int> getNumericId, params T[] instances)
|
2013-02-12 04:47:36 +06:00
|
|
|
{
|
2016-05-26 17:12:04 +02:00
|
|
|
if (refresherGuid == Guid.Empty || instances.Length == 0 || getNumericId == null) return;
|
2014-03-21 17:04:30 +11:00
|
|
|
|
2016-08-23 11:17:08 +02:00
|
|
|
Current.ServerMessenger.PerformRefresh(
|
2016-08-24 12:28:31 +02:00
|
|
|
Current.ServerRegistrar.Registrations,
|
2016-05-26 17:12:04 +02:00
|
|
|
GetRefresherById(refresherGuid),
|
2013-02-12 04:47:36 +06:00
|
|
|
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>
|
2016-05-26 17:12:04 +02:00
|
|
|
/// <param name="refresherGuid">The unique identifier of the ICacheRefresher.</param>
|
2015-03-04 12:16:28 +01:00
|
|
|
/// <param name="id">The unique identifier of the invalidated item.</param>
|
2016-05-26 17:12:04 +02:00
|
|
|
public void Refresh(Guid refresherGuid, int id)
|
2013-02-07 03:22:38 +06:00
|
|
|
{
|
2016-05-26 17:12:04 +02:00
|
|
|
if (refresherGuid == Guid.Empty || id == default(int)) return;
|
2014-03-21 17:04:30 +11:00
|
|
|
|
2016-08-23 11:17:08 +02:00
|
|
|
Current.ServerMessenger.PerformRefresh(
|
2016-08-24 12:28:31 +02:00
|
|
|
Current.ServerRegistrar.Registrations,
|
2016-05-26 17:12:04 +02:00
|
|
|
GetRefresherById(refresherGuid),
|
2013-02-12 03:46:27 +06:00
|
|
|
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>
|
2016-05-26 17:12:04 +02:00
|
|
|
/// <param name="refresherGuid">The unique identifier of the ICacheRefresher.</param>
|
2015-03-04 12:16:28 +01:00
|
|
|
/// <param name="id">The unique identifier of the invalidated item.</param>
|
2016-05-26 17:12:04 +02:00
|
|
|
public void Refresh(Guid refresherGuid, Guid id)
|
2013-02-07 03:22:38 +06:00
|
|
|
{
|
2016-05-26 17:12:04 +02:00
|
|
|
if (refresherGuid == Guid.Empty || id == Guid.Empty) return;
|
2014-03-21 17:04:30 +11:00
|
|
|
|
2016-08-23 11:17:08 +02:00
|
|
|
Current.ServerMessenger.PerformRefresh(
|
2016-08-24 12:28:31 +02:00
|
|
|
Current.ServerRegistrar.Registrations,
|
2016-05-26 17:12:04 +02:00
|
|
|
GetRefresherById(refresherGuid),
|
2013-02-12 03:46:27 +06:00
|
|
|
id);
|
2013-02-07 03:22:38 +06:00
|
|
|
}
|
|
|
|
|
|
2016-05-26 17:12:04 +02:00
|
|
|
// payload should be an object, or array of objects, NOT a
|
|
|
|
|
// Linq enumerable of some sort (IEnumerable, query...)
|
|
|
|
|
public void RefreshByPayload<TPayload>(Guid refresherGuid, TPayload[] payload)
|
2015-04-08 14:21:58 +02:00
|
|
|
{
|
2016-05-26 17:12:04 +02:00
|
|
|
if (refresherGuid == Guid.Empty || payload == null) return;
|
2015-04-08 14:21:58 +02:00
|
|
|
|
2016-08-23 11:17:08 +02:00
|
|
|
Current.ServerMessenger.PerformRefresh(
|
2016-08-24 12:28:31 +02:00
|
|
|
Current.ServerRegistrar.Registrations,
|
2016-05-26 17:12:04 +02:00
|
|
|
GetRefresherById(refresherGuid),
|
2015-04-08 14:21:58 +02:00
|
|
|
payload);
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-26 17:12:04 +02:00
|
|
|
// so deal with IEnumerable
|
|
|
|
|
public void RefreshByPayload<TPayload>(Guid refresherGuid, IEnumerable<TPayload> payloads)
|
|
|
|
|
where TPayload : class
|
|
|
|
|
{
|
|
|
|
|
if (refresherGuid == Guid.Empty || payloads == null) return;
|
|
|
|
|
|
2016-08-23 11:17:08 +02:00
|
|
|
Current.ServerMessenger.PerformRefresh(
|
2016-08-24 12:28:31 +02:00
|
|
|
Current.ServerRegistrar.Registrations,
|
2016-05-26 17:12:04 +02:00
|
|
|
GetRefresherById(refresherGuid),
|
|
|
|
|
payloads.ToArray());
|
|
|
|
|
}
|
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>
|
2016-05-26 17:12:04 +02:00
|
|
|
/// <param name="refresherGuid">The unique identifier of the ICacheRefresher.</param>
|
2015-03-04 12:16:28 +01:00
|
|
|
/// <param name="jsonPayload">The notification content.</param>
|
2016-05-26 17:12:04 +02:00
|
|
|
public void RefreshByJson(Guid refresherGuid, string jsonPayload)
|
2013-03-21 20:30:32 +06:00
|
|
|
{
|
2016-05-26 17:12:04 +02:00
|
|
|
if (refresherGuid == Guid.Empty || jsonPayload.IsNullOrWhiteSpace()) return;
|
2014-03-21 17:04:30 +11:00
|
|
|
|
2016-08-23 11:17:08 +02:00
|
|
|
Current.ServerMessenger.PerformRefresh(
|
2016-08-24 12:28:31 +02:00
|
|
|
Current.ServerRegistrar.Registrations,
|
2016-05-26 17:12:04 +02:00
|
|
|
GetRefresherById(refresherGuid),
|
2013-03-21 20:30:32 +06:00
|
|
|
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;
|
|
|
|
|
|
2016-08-23 11:17:08 +02:00
|
|
|
// Current.ServerMessenger.Notify(
|
2016-08-24 12:28:31 +02:00
|
|
|
// Current.ServerRegistrar.Registrations,
|
2015-03-04 12:16:28 +01:00
|
|
|
// 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>
|
2016-05-26 17:12:04 +02:00
|
|
|
/// <param name="refresherGuid">The unique identifier of the ICacheRefresher.</param>
|
|
|
|
|
public void RefreshAll(Guid refresherGuid)
|
2013-03-16 01:37:05 +06:00
|
|
|
{
|
2016-05-26 17:12:04 +02:00
|
|
|
if (refresherGuid == Guid.Empty) return;
|
2015-10-27 19:24:56 +01:00
|
|
|
|
2016-08-23 11:17:08 +02:00
|
|
|
Current.ServerMessenger.PerformRefreshAll(
|
2016-08-24 12:28:31 +02:00
|
|
|
Current.ServerRegistrar.Registrations,
|
2016-05-26 17:12:04 +02:00
|
|
|
GetRefresherById(refresherGuid));
|
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>
|
2016-05-26 17:12:04 +02:00
|
|
|
/// <param name="refresherGuid">The unique identifier of the ICacheRefresher.</param>
|
2015-03-04 12:16:28 +01:00
|
|
|
/// <param name="id">The unique identifier of the removed item.</param>
|
2016-05-26 17:12:04 +02:00
|
|
|
public void Remove(Guid refresherGuid, int id)
|
2013-02-07 03:22:38 +06:00
|
|
|
{
|
2016-05-26 17:12:04 +02:00
|
|
|
if (refresherGuid == Guid.Empty || id == default(int)) return;
|
2014-03-21 17:04:30 +11:00
|
|
|
|
2016-08-23 11:17:08 +02:00
|
|
|
Current.ServerMessenger.PerformRemove(
|
2016-08-24 12:28:31 +02:00
|
|
|
Current.ServerRegistrar.Registrations,
|
2016-05-26 17:12:04 +02:00
|
|
|
GetRefresherById(refresherGuid),
|
2013-02-12 03:46:27 +06:00
|
|
|
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>
|
2016-05-26 17:12:04 +02:00
|
|
|
/// <param name="refresherGuid">The unique identifier of the ICacheRefresher.</param>
|
2015-03-04 12:16:28 +01:00
|
|
|
/// <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>
|
2016-05-26 17:12:04 +02:00
|
|
|
public void Remove<T>(Guid refresherGuid, Func<T, int> getNumericId, params T[] instances)
|
2013-02-12 07:35:47 +06:00
|
|
|
{
|
2016-08-23 11:17:08 +02:00
|
|
|
Current.ServerMessenger.PerformRemove(
|
2016-08-24 12:28:31 +02:00
|
|
|
Current.ServerRegistrar.Registrations,
|
2016-05-26 17:12:04 +02:00
|
|
|
GetRefresherById(refresherGuid),
|
2013-02-12 07:35:47 +06:00
|
|
|
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
|
2016-05-26 17:12:04 +02:00
|
|
|
private static ICacheRefresher GetRefresherById(Guid refresherGuid)
|
2013-02-07 04:26:48 +06:00
|
|
|
{
|
2016-08-13 16:02:35 +02:00
|
|
|
return Current.CacheRefreshers[refresherGuid];
|
2013-02-07 03:22:38 +06:00
|
|
|
}
|
|
|
|
|
}
|
2014-03-25 20:37:20 -07:00
|
|
|
}
|