From 77981f889ffc27053e9643577e12eec843760629 Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 21 Mar 2017 11:10:52 +0100 Subject: [PATCH] U4-9582 - perfs, cache converter prevalues --- .../ValueConverters/SliderValueConverter.cs | 26 +++++++++++++---- .../ValueConverters/TagsValueConverter.cs | 29 +++++++++++++------ .../Cache/DataTypeCacheRefresher.cs | 6 ++++ .../MultipleMediaPickerPropertyConverter.cs | 26 +++++++++++++---- 4 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/SliderValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/SliderValueConverter.cs index f3354eb631..93cdd95cab 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/SliderValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/SliderValueConverter.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Linq; using Umbraco.Core.Configuration; using Umbraco.Core.Models; @@ -88,13 +89,26 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters /// private bool IsRangeDataType(int dataTypeId) { - // ** This must be cached (U4-8862) ** - var enableRange = - _dataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeId) - .PreValuesAsDictionary.FirstOrDefault( - x => string.Equals(x.Key, "enableRange", StringComparison.InvariantCultureIgnoreCase)).Value; + // GetPreValuesCollectionByDataTypeId is cached at repository level; + // still, the collection is deep-cloned so this is kinda expensive, + // better to cache here + trigger refresh in DataTypeCacheRefresher - return enableRange != null && enableRange.Value.TryConvertTo().Result; + return Storages.GetOrAdd(dataTypeId, id => + { + var preValue = _dataTypeService.GetPreValuesCollectionByDataTypeId(id) + .PreValuesAsDictionary + .FirstOrDefault(x => string.Equals(x.Key, "enableRange", StringComparison.InvariantCultureIgnoreCase)) + .Value; + + return preValue != null && preValue.Value.TryConvertTo().Result; + }); + } + + private static readonly ConcurrentDictionary Storages = new ConcurrentDictionary(); + + internal static void ClearCaches() + { + Storages.Clear(); } } } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs index 8b53492515..b085748487 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs @@ -1,9 +1,12 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Umbraco.Core.Configuration; +using Umbraco.Core.Events; +using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Services; @@ -74,18 +77,26 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters /// private bool JsonStorageType(int dataTypeId) { - // ** This must be cached (U4-8862) ** - var storageType = - _dataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeId) - .PreValuesAsDictionary.FirstOrDefault( - x => string.Equals(x.Key, "storageType", StringComparison.InvariantCultureIgnoreCase)).Value; + // GetPreValuesCollectionByDataTypeId is cached at repository level; + // still, the collection is deep-cloned so this is kinda expensive, + // better to cache here + trigger refresh in DataTypeCacheRefresher - if (storageType != null && storageType.Value.InvariantEquals("Json")) + return Storages.GetOrAdd(dataTypeId, id => { - return true; - } + var preValue = _dataTypeService.GetPreValuesCollectionByDataTypeId(id) + .PreValuesAsDictionary + .FirstOrDefault(x => string.Equals(x.Key, "storageType", StringComparison.InvariantCultureIgnoreCase)) + .Value; - return false; + return preValue != null && preValue.Value.InvariantEquals("json"); + }); + } + + private static readonly ConcurrentDictionary Storages = new ConcurrentDictionary(); + + internal static void ClearCaches() + { + Storages.Clear(); } } } diff --git a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs index 11b3ab6294..fe629a6ccf 100644 --- a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs @@ -5,6 +5,8 @@ using Umbraco.Core.Cache; using System.Linq; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.PropertyEditors.ValueConverters; +using Umbraco.Web.PropertyEditors.ValueConverters; namespace Umbraco.Web.Cache @@ -111,6 +113,10 @@ namespace Umbraco.Web.Cache PublishedContentType.ClearDataType(payload.Id); }); + TagsValueConverter.ClearCaches(); + MultipleMediaPickerPropertyConverter.ClearCaches(); + SliderValueConverter.ClearCaches(); + base.Refresh(jsonPayload); } } diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MultipleMediaPickerPropertyConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MultipleMediaPickerPropertyConverter.cs index 72d746d779..ddb50a0e31 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MultipleMediaPickerPropertyConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MultipleMediaPickerPropertyConverter.cs @@ -8,6 +8,7 @@ // -------------------------------------------------------------------------------------------------------------------- using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -223,13 +224,26 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters /// public bool IsMultipleDataType(int dataTypeId) { - // ** This must be cached (U4-8862) ** - var multiPickerPreValue = - _dataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeId) - .PreValuesAsDictionary.FirstOrDefault( - x => string.Equals(x.Key, "multiPicker", StringComparison.InvariantCultureIgnoreCase)).Value; + // GetPreValuesCollectionByDataTypeId is cached at repository level; + // still, the collection is deep-cloned so this is kinda expensive, + // better to cache here + trigger refresh in DataTypeCacheRefresher - return multiPickerPreValue != null && multiPickerPreValue.Value.TryConvertTo().Result; + return Storages.GetOrAdd(dataTypeId, id => + { + var preValue = _dataTypeService.GetPreValuesCollectionByDataTypeId(id) + .PreValuesAsDictionary + .FirstOrDefault(x => string.Equals(x.Key, "multiPicker", StringComparison.InvariantCultureIgnoreCase)) + .Value; + + return preValue != null && preValue.Value.TryConvertTo().Result; + }); + } + + private static readonly ConcurrentDictionary Storages = new ConcurrentDictionary(); + + internal static void ClearCaches() + { + Storages.Clear(); } } } \ No newline at end of file