Compare commits

...

1 Commits

Author SHA1 Message Date
Stephan d0ab80bfde Support clearing all datatype cache 2019-02-08 11:40:49 +01:00
6 changed files with 50 additions and 11 deletions
@@ -99,6 +99,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
if (requiresCacheRebuild)
{
var dataTypeCacheRefresher = _cacheRefreshers[Guid.Parse("35B16C25-A17E-45D7-BC8F-EDAB1DCC28D2")];
// TODO: this should use DistributedCache not messengers, alas DistributedCache lives in Umbraco.Web
_serverMessenger.PerformRefreshAll(dataTypeCacheRefresher);
}
}
@@ -87,6 +87,10 @@ namespace Umbraco.Core.Models.PublishedContent
{
lock (_publishedDataTypesLocker)
{
// no ids = force-refresh all
if (ids.Length == 0)
_publishedDataTypes = null;
if (_publishedDataTypes == null)
{
var dataTypes = _dataTypeService.GetAll();
@@ -1,10 +1,9 @@
using System;
using System.Linq;
using Umbraco.Core.Cache;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors.ValueConverters;
using Umbraco.Core.Services;
using Umbraco.Web.PropertyEditors;
using Umbraco.Web.PropertyEditors.ValueConverters;
using Umbraco.Web.PublishedCache;
@@ -49,11 +48,18 @@ namespace Umbraco.Web.Cache
ClearAllIsolatedCacheByEntityType<IMember>();
ClearAllIsolatedCacheByEntityType<IMemberType>();
var dataTypeCache = AppCaches.IsolatedCaches.Get<IDataType>();
// zero id and key means "all"
var isAll = payloads.Any(x => x.Id == 0 && x.Key == Guid.Empty);
foreach (var payload in payloads)
if (isAll)
{
_idkMap.ClearCache(payload.Id);
// TODO: this is a bit extreme, we should have ways to clear only some types
_idkMap.ClearCache();
}
else
{
foreach (var payload in payloads)
_idkMap.ClearCache(payload.Id);
}
// TODO: not sure I like these?
@@ -71,7 +77,10 @@ namespace Umbraco.Web.Cache
public override void RefreshAll()
{
throw new NotSupportedException();
// TODO: this is temp, because we need to trigger a refresh for Core
// but really, all this should be *in* Core and this should throw!
Refresh(new[] { new JsonPayload() });
//throw new NotSupportedException();
}
public override void Refresh(int id)
@@ -95,6 +104,13 @@ namespace Umbraco.Web.Cache
public class JsonPayload
{
public JsonPayload()
{
// "all"
Id = 0;
Key = Guid.Empty;
}
public JsonPayload(int id, Guid key, bool removed)
{
Id = id;
@@ -107,6 +123,9 @@ namespace Umbraco.Web.Cache
public Guid Key { get; }
public bool Removed { get; }
// zero id and key means "all"
public bool IsAll() => Id == 0 && Key == Guid.Empty;
}
#endregion
@@ -86,6 +86,12 @@ namespace Umbraco.Web.Cache
#region DataTypeCache
public static void RefreshDataTypeCache(this DistributedCache dc)
{
var payloads = new[] { new DataTypeCacheRefresher.JsonPayload() };
dc.RefreshByPayload(DataTypeCacheRefresher.UniqueId, payloads);
}
public static void RefreshDataTypeCache(this DistributedCache dc, IDataType dataType)
{
if (dataType == null) return;
@@ -364,15 +364,21 @@ namespace Umbraco.Web.PublishedCache.NuCache
public void UpdateDataTypes(IEnumerable<int> dataTypeIds, Func<int, PublishedContentType> getContentType)
{
var dataTypeIdsA = dataTypeIds.ToArray();
var isAll = dataTypeIdsA.Length == 0; // empty array = all
var lockInfo = new WriteLockInfo();
try
{
Lock(lockInfo);
var contentTypes = _contentTypesById
.Where(kvp =>
var temp = isAll
? _contentTypesById
: _contentTypesById.Where(kvp =>
kvp.Value.Value != null &&
kvp.Value.Value.PropertyTypes.Any(p => dataTypeIds.Contains(p.DataType.Id)))
kvp.Value.Value.PropertyTypes.Any(p => dataTypeIdsA.Contains(p.DataType.Id)));
var contentTypes = temp
.Select(kvp => kvp.Value.Value)
.Select(x => getContentType(x.Id))
.Where(x => x != null) // poof, gone, very unlikely and probably an anomaly
@@ -794,9 +794,12 @@ namespace Umbraco.Web.PublishedCache.NuCache
if (_isReady == false)
return;
var isAll = payloads.Any(x => x.IsAll());
var idsA = payloads.Select(x => x.Id).ToArray();
foreach (var payload in payloads)
if (isAll)
_logger.Debug<PublishedSnapshotService>("Notified Refreshed for all data types");
else foreach (var payload in payloads)
_logger.Debug<PublishedSnapshotService>("Notified {RemovedStatus} for data type {DataTypeId}",
payload.Removed ? "Removed" : "Refreshed",
payload.Id);
@@ -808,7 +811,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
// this is triggering datatypes reload in the factory, and right after we create some
// content types by loading them ... there's a race condition here, which would require
// some locking on datatypes
_publishedContentTypeFactory.NotifyDataTypeChanges(idsA);
_publishedContentTypeFactory.NotifyDataTypeChanges(isAll ? Array.Empty<int>() : idsA); // empty array = all
using (var scope = _scopeProvider.CreateScope())
{