Clear elements cache instead of refreshing it (#17708)
This commit is contained in:
@@ -45,7 +45,7 @@ internal sealed class CacheRefreshingNotificationHandler :
|
||||
|
||||
public async Task HandleAsync(ContentRefreshNotification notification, CancellationToken cancellationToken)
|
||||
{
|
||||
await RefreshElementsCacheAsync(notification.Entity);
|
||||
ClearElementsCache();
|
||||
|
||||
await _documentCacheService.RefreshContentAsync(notification.Entity);
|
||||
}
|
||||
@@ -54,14 +54,14 @@ internal sealed class CacheRefreshingNotificationHandler :
|
||||
{
|
||||
foreach (IContent deletedEntity in notification.DeletedEntities)
|
||||
{
|
||||
RemoveFromElementsCache(deletedEntity);
|
||||
ClearElementsCache();
|
||||
await _documentCacheService.DeleteItemAsync(deletedEntity);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task HandleAsync(MediaRefreshNotification notification, CancellationToken cancellationToken)
|
||||
{
|
||||
await RefreshElementsCacheAsync(notification.Entity);
|
||||
ClearElementsCache();
|
||||
await _mediaCacheService.RefreshMediaAsync(notification.Entity);
|
||||
}
|
||||
|
||||
@@ -69,58 +69,21 @@ internal sealed class CacheRefreshingNotificationHandler :
|
||||
{
|
||||
foreach (IMedia deletedEntity in notification.DeletedEntities)
|
||||
{
|
||||
RemoveFromElementsCache(deletedEntity);
|
||||
ClearElementsCache();
|
||||
await _mediaCacheService.DeleteItemAsync(deletedEntity);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RefreshElementsCacheAsync(IUmbracoEntity content)
|
||||
private void ClearElementsCache()
|
||||
{
|
||||
IEnumerable<IRelation> parentRelations = _relationService.GetByParent(content)!;
|
||||
IEnumerable<IRelation> childRelations = _relationService.GetByChild(content);
|
||||
|
||||
var ids = parentRelations.Select(x => x.ChildId).Concat(childRelations.Select(x => x.ParentId)).ToHashSet();
|
||||
// We need to add ourselves to the list of ids to clear
|
||||
ids.Add(content.Id);
|
||||
foreach (var id in ids)
|
||||
{
|
||||
if (await _documentCacheService.HasContentByIdAsync(id) is false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IPublishedContent? publishedContent = await _documentCacheService.GetByIdAsync(id);
|
||||
if (publishedContent is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (IPublishedProperty publishedProperty in publishedContent.Properties)
|
||||
{
|
||||
var property = (PublishedProperty) publishedProperty;
|
||||
if (property.ReferenceCacheLevel is PropertyCacheLevel.Elements
|
||||
|| property.PropertyType.DeliveryApiCacheLevel is PropertyCacheLevel.Elements
|
||||
|| property.PropertyType.DeliveryApiCacheLevelForExpansion is PropertyCacheLevel.Elements)
|
||||
{
|
||||
_elementsCache.ClearByKey(property.ValuesCacheKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ideally we'd like to not have to clear the entire cache here. However, this was the existing behavior in NuCache.
|
||||
// The reason for this is that we have no way to know which elements are affected by the changes. or what their keys are.
|
||||
// This is because currently published elements lives exclusively in a JSON blob in the umbracoPropertyData table.
|
||||
// This means that the only way to resolve these keys are to actually parse this data with a specific value converter, and for all cultures, which is not feasible.
|
||||
// If published elements become their own entities with relations, instead of just property data, we can revisit this,
|
||||
_elementsCache.Clear();
|
||||
}
|
||||
|
||||
private void RemoveFromElementsCache(IUmbracoEntity content)
|
||||
{
|
||||
// ClearByKey clears by "startsWith" so we'll clear by the cachekey prefix + contentKey
|
||||
// This will clear any and all properties for this content item, this is important because
|
||||
// we cannot resolve the PublishedContent for this entity since it and its content type is deleted.
|
||||
_elementsCache.ClearByKey(GetContentWideCacheKey(content.Key, true));
|
||||
_elementsCache.ClearByKey(GetContentWideCacheKey(content.Key, false));
|
||||
}
|
||||
|
||||
private string GetContentWideCacheKey(Guid contentKey, bool isPreviewing) => isPreviewing
|
||||
? CacheKeys.PreviewPropertyCacheKeyPrefix + contentKey
|
||||
: CacheKeys.PropertyCacheKeyPrefix + contentKey;
|
||||
|
||||
public Task HandleAsync(ContentTypeRefreshedNotification notification, CancellationToken cancellationToken)
|
||||
{
|
||||
const ContentTypeChangeTypes types // only for those that have been refreshed
|
||||
|
||||
Reference in New Issue
Block a user