2021-02-18 11:06:02 +01:00
|
|
|
using Umbraco.Cms.Core.Sync;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-07 15:28:38 +02:00
|
|
|
namespace Umbraco.Cms.Core.Cache;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// Represents the entry point into Umbraco's distributed cache infrastructure.
|
2022-06-07 15:28:38 +02:00
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
2023-06-20 11:15:47 +02: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 and Examine/Lucene indexes.
|
|
|
|
|
/// indexes
|
|
|
|
|
/// </para>
|
2022-06-07 15:28:38 +02:00
|
|
|
/// </remarks>
|
|
|
|
|
public sealed class DistributedCache
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2022-06-07 15:28:38 +02:00
|
|
|
private readonly IServerMessenger _serverMessenger;
|
2023-06-20 11:15:47 +02:00
|
|
|
private readonly CacheRefresherCollection _cacheRefreshers;
|
2022-06-07 15:28:38 +02:00
|
|
|
|
2023-06-20 11:15:47 +02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="DistributedCache" /> class.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="serverMessenger">The server messenger.</param>
|
|
|
|
|
/// <param name="cacheRefreshers">The cache refreshers.</param>
|
2022-06-07 15:28:38 +02:00
|
|
|
public DistributedCache(IServerMessenger serverMessenger, CacheRefresherCollection cacheRefreshers)
|
|
|
|
|
{
|
|
|
|
|
_serverMessenger = serverMessenger;
|
|
|
|
|
_cacheRefreshers = cacheRefreshers;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-29 19:52:40 +02:00
|
|
|
/// <summary>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// Notifies the distributed cache of specified item invalidation, for a specified <see cref="ICacheRefresher{T}" />.
|
2018-06-29 19:52:40 +02:00
|
|
|
/// </summary>
|
2022-06-07 15:28:38 +02:00
|
|
|
/// <typeparam name="T">The type of the invalidated items.</typeparam>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// <param name="refresherGuid">The unique identifier of the cache refresher.</param>
|
2022-06-07 15:28:38 +02:00
|
|
|
/// <param name="getNumericId">A function returning the unique identifier of items.</param>
|
|
|
|
|
/// <param name="instances">The invalidated items.</param>
|
2018-06-29 19:52:40 +02:00
|
|
|
/// <remarks>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// This method is much better for performance because it does not need to re-lookup object instances.
|
2018-06-29 19:52:40 +02:00
|
|
|
/// </remarks>
|
2022-06-07 15:28:38 +02:00
|
|
|
public void Refresh<T>(Guid refresherGuid, Func<T, int> getNumericId, params T[] instances)
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2023-06-20 11:15:47 +02:00
|
|
|
if (refresherGuid == Guid.Empty || getNumericId is null || instances is null || instances.Length == 0)
|
2019-12-19 10:43:00 +01:00
|
|
|
{
|
2022-06-07 15:28:38 +02:00
|
|
|
return;
|
2019-12-19 10:43:00 +01:00
|
|
|
}
|
|
|
|
|
|
2023-06-20 11:15:47 +02:00
|
|
|
_serverMessenger.QueueRefresh(GetRefresherById(refresherGuid), getNumericId, instances);
|
2022-06-07 15:28:38 +02:00
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-07 15:28:38 +02:00
|
|
|
// helper method to get an ICacheRefresher by its unique identifier
|
|
|
|
|
private ICacheRefresher GetRefresherById(Guid refresherGuid)
|
2023-06-20 11:15:47 +02:00
|
|
|
=> _cacheRefreshers[refresherGuid] ?? throw new InvalidOperationException($"No cache refresher found with id {refresherGuid}");
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Notifies the distributed cache of a specified item invalidation, for a specified <see cref="ICacheRefresher" />.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="refresherGuid">The unique identifier of the cache refresher.</param>
|
|
|
|
|
/// <param name="id">The unique identifier of the invalidated item.</param>
|
|
|
|
|
public void Refresh(Guid refresherGuid, int id)
|
2022-06-07 15:28:38 +02:00
|
|
|
{
|
2023-06-20 11:15:47 +02:00
|
|
|
if (refresherGuid == Guid.Empty || id == default)
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2023-06-20 11:15:47 +02:00
|
|
|
return;
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
|
2023-06-20 11:15:47 +02:00
|
|
|
_serverMessenger.QueueRefresh(GetRefresherById(refresherGuid), id);
|
2022-06-07 15:28:38 +02:00
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-07 15:28:38 +02:00
|
|
|
/// <summary>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// Notifies the distributed cache of a specified item invalidation, for a specified <see cref="ICacheRefresher" />.
|
2022-06-07 15:28:38 +02:00
|
|
|
/// </summary>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// <param name="refresherGuid">The unique identifier of the cache refresher.</param>
|
|
|
|
|
/// <param name="ids">The unique identifier of the invalidated items.</param>
|
|
|
|
|
public void Refresh(Guid refresherGuid, params int[] ids)
|
2022-06-07 15:28:38 +02:00
|
|
|
{
|
2023-06-20 11:15:47 +02:00
|
|
|
if (refresherGuid == Guid.Empty || ids is null || ids.Length == 0)
|
2022-06-07 15:28:38 +02:00
|
|
|
{
|
|
|
|
|
return;
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
|
2023-06-20 11:15:47 +02:00
|
|
|
_serverMessenger.QueueRefresh(GetRefresherById(refresherGuid), ids);
|
2022-06-07 15:28:38 +02:00
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-07 15:28:38 +02:00
|
|
|
/// <summary>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// Notifies the distributed cache of a specified item invalidation, for a specified <see cref="ICacheRefresher" />.
|
2022-06-07 15:28:38 +02:00
|
|
|
/// </summary>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// <param name="refresherGuid">The unique identifier of the cache refresher.</param>
|
2022-06-07 15:28:38 +02:00
|
|
|
/// <param name="id">The unique identifier of the invalidated item.</param>
|
|
|
|
|
public void Refresh(Guid refresherGuid, Guid id)
|
|
|
|
|
{
|
|
|
|
|
if (refresherGuid == Guid.Empty || id == Guid.Empty)
|
|
|
|
|
{
|
|
|
|
|
return;
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
|
2023-06-20 11:15:47 +02:00
|
|
|
_serverMessenger.QueueRefresh(GetRefresherById(refresherGuid), id);
|
2022-06-07 15:28:38 +02:00
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2023-06-20 11:15:47 +02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Refreshes the distributed cache by payload.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="TPayload">The type of the payload.</typeparam>
|
|
|
|
|
/// <param name="refresherGuid">The unique identifier of the cache refresher.</param>
|
|
|
|
|
/// <param name="payload">The payload.</param>
|
2022-06-07 15:28:38 +02:00
|
|
|
public void RefreshByPayload<TPayload>(Guid refresherGuid, TPayload[] payload)
|
|
|
|
|
{
|
2023-06-20 11:15:47 +02:00
|
|
|
if (refresherGuid == Guid.Empty || payload is null || payload.Length == 0)
|
2022-06-07 15:28:38 +02:00
|
|
|
{
|
|
|
|
|
return;
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
|
2023-06-20 11:15:47 +02:00
|
|
|
_serverMessenger.QueueRefresh(GetRefresherById(refresherGuid), payload);
|
2022-06-07 15:28:38 +02:00
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2023-06-20 11:15:47 +02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Refreshes the distributed cache by payload.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="TPayload">The type of the payload.</typeparam>
|
|
|
|
|
/// <param name="refresherGuid">The unique identifier of the cache refresher.</param>
|
|
|
|
|
/// <param name="payloads">The payloads.</param>
|
2022-06-07 15:28:38 +02:00
|
|
|
public void RefreshByPayload<TPayload>(Guid refresherGuid, IEnumerable<TPayload> payloads)
|
|
|
|
|
where TPayload : class
|
2023-06-20 11:15:47 +02:00
|
|
|
=> RefreshByPayload(refresherGuid, payloads.ToArray());
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Notifies the distributed cache of a global invalidation for a specified <see cref="ICacheRefresher" />.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="refresherGuid">The unique identifier of the cache refresher.</param>
|
|
|
|
|
public void RefreshAll(Guid refresherGuid)
|
2022-06-07 15:28:38 +02:00
|
|
|
{
|
2023-06-20 11:15:47 +02:00
|
|
|
if (refresherGuid == Guid.Empty)
|
2022-06-07 15:28:38 +02:00
|
|
|
{
|
|
|
|
|
return;
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
|
2023-06-20 11:15:47 +02:00
|
|
|
_serverMessenger.QueueRefreshAll(GetRefresherById(refresherGuid));
|
2022-06-07 15:28:38 +02:00
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-07 15:28:38 +02:00
|
|
|
/// <summary>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// Notifies the distributed cache of a specified item removal, for a specified <see cref="ICacheRefresher" />.
|
2022-06-07 15:28:38 +02:00
|
|
|
/// </summary>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// <param name="refresherGuid">The unique identifier of the cache refresher.</param>
|
|
|
|
|
/// <param name="id">The unique identifier of the removed item.</param>
|
|
|
|
|
public void Remove(Guid refresherGuid, int id)
|
2022-06-07 15:28:38 +02:00
|
|
|
{
|
2023-06-20 11:15:47 +02:00
|
|
|
if (refresherGuid == Guid.Empty || id == default)
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2022-06-07 15:28:38 +02:00
|
|
|
return;
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
|
2023-06-20 11:15:47 +02:00
|
|
|
_serverMessenger.QueueRemove(GetRefresherById(refresherGuid), id);
|
2022-06-07 15:28:38 +02:00
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-06-07 15:28:38 +02:00
|
|
|
/// <summary>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// Notifies the distributed cache of a specified item removal, for a specified <see cref="ICacheRefresher" />.
|
2022-06-07 15:28:38 +02:00
|
|
|
/// </summary>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// <param name="refresherGuid">The unique identifier of the cache refresher.</param>
|
|
|
|
|
/// <param name="ids">The unique identifier of the removed items.</param>
|
|
|
|
|
public void Remove(Guid refresherGuid, params int[] ids)
|
2022-06-07 15:28:38 +02:00
|
|
|
{
|
2023-06-20 11:15:47 +02:00
|
|
|
if (refresherGuid == Guid.Empty || ids is null || ids.Length == 0)
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2022-06-07 15:28:38 +02:00
|
|
|
return;
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
2022-06-07 15:28:38 +02:00
|
|
|
|
2023-06-20 11:15:47 +02:00
|
|
|
_serverMessenger.QueueRemove(GetRefresherById(refresherGuid), ids);
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
2022-06-07 15:28:38 +02:00
|
|
|
|
|
|
|
|
/// <summary>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// Notifies the distributed cache of specified item removal, for a specified <see cref="ICacheRefresher{T}" />.
|
2022-06-07 15:28:38 +02:00
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T">The type of the removed items.</typeparam>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// <param name="refresherGuid">The unique identifier of the cache refresher.</param>
|
2022-06-07 15:28:38 +02:00
|
|
|
/// <param name="getNumericId">A function returning the unique identifier of items.</param>
|
|
|
|
|
/// <param name="instances">The removed items.</param>
|
|
|
|
|
/// <remarks>
|
2023-06-20 11:15:47 +02:00
|
|
|
/// This method is much better for performance because it does not need to re-lookup object instances.
|
2022-06-07 15:28:38 +02:00
|
|
|
/// </remarks>
|
2023-06-20 11:15:47 +02:00
|
|
|
public void Remove<T>(Guid refresherGuid, Func<T, int> getNumericId, params T[] instances)
|
|
|
|
|
{
|
|
|
|
|
if (refresherGuid == Guid.Empty || getNumericId is null || instances is null || instances.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-06-07 15:28:38 +02:00
|
|
|
|
2023-06-20 11:15:47 +02:00
|
|
|
_serverMessenger.QueueRemove(GetRefresherById(refresherGuid), getNumericId, instances);
|
|
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|