using Umbraco.Cms.Core.Sync;
namespace Umbraco.Cms.Core.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 and Examine/Lucene indexes.
/// indexes
///
///
public sealed class DistributedCache
{
private readonly IServerMessenger _serverMessenger;
private readonly CacheRefresherCollection _cacheRefreshers;
///
/// Initializes a new instance of the class.
///
/// The server messenger.
/// The cache refreshers.
public DistributedCache(IServerMessenger serverMessenger, CacheRefresherCollection cacheRefreshers)
{
_serverMessenger = serverMessenger;
_cacheRefreshers = cacheRefreshers;
}
///
/// Notifies the distributed cache of specified item invalidation, for a specified .
///
/// The type of the invalidated items.
/// The unique identifier of the cache refresher.
/// 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 || getNumericId is null || instances is null || instances.Length == 0)
{
return;
}
_serverMessenger.QueueRefresh(GetRefresherById(refresherGuid), getNumericId, instances);
}
// helper method to get an ICacheRefresher by its unique identifier
private ICacheRefresher GetRefresherById(Guid refresherGuid)
=> _cacheRefreshers[refresherGuid] ?? throw new InvalidOperationException($"No cache refresher found with id {refresherGuid}");
///
/// Notifies the distributed cache of a specified item invalidation, for a specified .
///
/// The unique identifier of the cache refresher.
/// The unique identifier of the invalidated item.
public void Refresh(Guid refresherGuid, int id)
{
if (refresherGuid == Guid.Empty || id == default)
{
return;
}
_serverMessenger.QueueRefresh(GetRefresherById(refresherGuid), id);
}
///
/// Notifies the distributed cache of a specified item invalidation, for a specified .
///
/// The unique identifier of the cache refresher.
/// The unique identifier of the invalidated items.
public void Refresh(Guid refresherGuid, params int[] ids)
{
if (refresherGuid == Guid.Empty || ids is null || ids.Length == 0)
{
return;
}
_serverMessenger.QueueRefresh(GetRefresherById(refresherGuid), ids);
}
///
/// Notifies the distributed cache of a specified item invalidation, for a specified .
///
/// The unique identifier of the cache refresher.
/// The unique identifier of the invalidated item.
public void Refresh(Guid refresherGuid, Guid id)
{
if (refresherGuid == Guid.Empty || id == Guid.Empty)
{
return;
}
_serverMessenger.QueueRefresh(GetRefresherById(refresherGuid), id);
}
///
/// Refreshes the distributed cache by payload.
///
/// The type of the payload.
/// The unique identifier of the cache refresher.
/// The payload.
public void RefreshByPayload(Guid refresherGuid, TPayload[] payload)
{
if (refresherGuid == Guid.Empty || payload is null || payload.Length == 0)
{
return;
}
_serverMessenger.QueueRefresh(GetRefresherById(refresherGuid), payload);
}
///
/// Refreshes the distributed cache by payload.
///
/// The type of the payload.
/// The unique identifier of the cache refresher.
/// The payloads.
public void RefreshByPayload(Guid refresherGuid, IEnumerable payloads)
where TPayload : class
=> RefreshByPayload(refresherGuid, payloads.ToArray());
///
/// Notifies the distributed cache of a global invalidation for a specified .
///
/// The unique identifier of the cache refresher.
public void RefreshAll(Guid refresherGuid)
{
if (refresherGuid == Guid.Empty)
{
return;
}
_serverMessenger.QueueRefreshAll(GetRefresherById(refresherGuid));
}
///
/// Notifies the distributed cache of a specified item removal, for a specified .
///
/// The unique identifier of the cache refresher.
/// The unique identifier of the removed item.
public void Remove(Guid refresherGuid, int id)
{
if (refresherGuid == Guid.Empty || id == default)
{
return;
}
_serverMessenger.QueueRemove(GetRefresherById(refresherGuid), id);
}
///
/// Notifies the distributed cache of a specified item removal, for a specified .
///
/// The unique identifier of the cache refresher.
/// The unique identifier of the removed items.
public void Remove(Guid refresherGuid, params int[] ids)
{
if (refresherGuid == Guid.Empty || ids is null || ids.Length == 0)
{
return;
}
_serverMessenger.QueueRemove(GetRefresherById(refresherGuid), ids);
}
///
/// Notifies the distributed cache of specified item removal, for a specified .
///
/// The type of the removed items.
/// The unique identifier of the cache refresher.
/// 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)
{
if (refresherGuid == Guid.Empty || getNumericId is null || instances is null || instances.Length == 0)
{
return;
}
_serverMessenger.QueueRemove(GetRefresherById(refresherGuid), getNumericId, instances);
}
}