diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedContentTypeFactory.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedContentTypeFactory.cs index 09e9a00389..009666aab5 100644 --- a/src/Umbraco.Core/Models/PublishedContent/IPublishedContentTypeFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedContentTypeFactory.cs @@ -60,5 +60,5 @@ public interface IPublishedContentTypeFactory /// This is so the factory can flush its caches. /// Invoked by the IPublishedSnapshotService. /// - void NotifyDataTypeChanges(int[] ids); + void NotifyDataTypeChanges(params int[] ids); } diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs index f2b1b9bbca..6cda67e975 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs @@ -10,8 +10,8 @@ public class PublishedContentTypeFactory : IPublishedContentTypeFactory { private readonly IDataTypeService _dataTypeService; private readonly PropertyValueConverterCollection _propertyValueConverters; - private readonly object _publishedDataTypesLocker = new(); private readonly IPublishedModelFactory _publishedModelFactory; + private object _publishedDataTypesLocker = new(); private Dictionary? _publishedDataTypes; public PublishedContentTypeFactory( @@ -52,19 +52,12 @@ public class PublishedContentTypeFactory : IPublishedContentTypeFactory /// public PublishedDataType GetDataType(int id) { - Dictionary? publishedDataTypes; - lock (_publishedDataTypesLocker) - { - if (_publishedDataTypes == null) - { - IEnumerable dataTypes = _dataTypeService.GetAll(); - _publishedDataTypes = dataTypes.ToDictionary(x => x.Id, CreatePublishedDataType); - } + Dictionary publishedDataTypes = LazyInitializer.EnsureInitialized( + ref _publishedDataTypes, + ref _publishedDataTypesLocker, + () => _dataTypeService.GetAll().ToDictionary(x => x.Id, CreatePublishedDataType)); - publishedDataTypes = _publishedDataTypes; - } - - if (publishedDataTypes is null || !publishedDataTypes.TryGetValue(id, out PublishedDataType? dataType)) + if (!publishedDataTypes.TryGetValue(id, out PublishedDataType? dataType)) { throw new ArgumentException($"Could not find a datatype with identifier {id}.", nameof(id)); } @@ -73,24 +66,31 @@ public class PublishedContentTypeFactory : IPublishedContentTypeFactory } /// - public void NotifyDataTypeChanges(int[] ids) + public void NotifyDataTypeChanges(params int[] ids) { + if (_publishedDataTypes is null) + { + // Not initialized yet, so skip and avoid lock + return; + } + lock (_publishedDataTypesLocker) { - if (_publishedDataTypes == null) + if (ids.Length == 0) { - IEnumerable dataTypes = _dataTypeService.GetAll(); - _publishedDataTypes = dataTypes.ToDictionary(x => x.Id, CreatePublishedDataType); + // Clear cache (and let it lazy initialize again later) + _publishedDataTypes = null; } else { + // Remove items from cache (in case the data type is removed) foreach (var id in ids) { _publishedDataTypes.Remove(id); } - IEnumerable dataTypes = _dataTypeService.GetAll(ids); - foreach (IDataType dataType in dataTypes) + // Update cacheB + foreach (IDataType dataType in _dataTypeService.GetAll(ids)) { _publishedDataTypes[dataType.Id] = CreatePublishedDataType(dataType); } diff --git a/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotService.cs b/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotService.cs index a7f8c42823..6ab806c8df 100644 --- a/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotService.cs @@ -189,6 +189,9 @@ internal class PublishedSnapshotService : IPublishedSnapshotService } } + // Ensure all published data types are updated + _publishedContentTypeFactory.NotifyDataTypeChanges(); + Notify(_contentStore, payloads, RefreshContentTypesLocked); Notify(_mediaStore, payloads, RefreshMediaTypesLocked);