From d9cb9f27f1946a61150aebe9bfa2f51c55f0f526 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 20 Apr 2020 22:25:05 +1000 Subject: [PATCH 1/4] ModelsBuilder enabled flag not respected When MB is disabled we were still rebuilding all of nucache models when schema changes are made which is a requirement of PureLive models but if MB is disabled then PureLive models don't matter. This was causing unnecessary performance and db overhead when modifying document types when mb is disabled. --- .../ILivePublishedModelFactory.cs | 11 +++++++++++ .../PublishedModelFactoryExtensions.cs | 19 +++++++++++-------- .../PureLiveModelFactory.cs | 9 ++++++++- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Core/Models/PublishedContent/ILivePublishedModelFactory.cs b/src/Umbraco.Core/Models/PublishedContent/ILivePublishedModelFactory.cs index 0810f2207b..0d7744389a 100644 --- a/src/Umbraco.Core/Models/PublishedContent/ILivePublishedModelFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/ILivePublishedModelFactory.cs @@ -1,5 +1,16 @@ namespace Umbraco.Core.Models.PublishedContent { + /// + /// Provides a live published model creation service. + /// + public interface ILivePublishedModelFactory2 : ILivePublishedModelFactory + { + /// + /// Tells the factory that it should build a new generation of models + /// + void Reset(); + } + /// /// Provides a live published model creation service. /// diff --git a/src/Umbraco.Core/PublishedModelFactoryExtensions.cs b/src/Umbraco.Core/PublishedModelFactoryExtensions.cs index ac8c9f1be7..cfb29038c6 100644 --- a/src/Umbraco.Core/PublishedModelFactoryExtensions.cs +++ b/src/Umbraco.Core/PublishedModelFactoryExtensions.cs @@ -50,14 +50,17 @@ namespace Umbraco.Core { lock (liveFactory.SyncRoot) { - // TODO: Fix this in 8.3! - We need to change the ILivePublishedModelFactory interface to have a Reset method and then when we have an embedded MB - // version we will publicize the ResetModels (and change the name to Reset). - // For now, this will suffice and we'll use reflection, there should be no other implementation of ILivePublishedModelFactory. - // Calling ResetModels resets the MB flag so that the next time EnsureModels is called (which is called when nucache lazily calls CreateModel) it will - // trigger the recompiling of pure live models. - var resetMethod = liveFactory.GetType().GetMethod("ResetModels", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); - if (resetMethod != null) - resetMethod.Invoke(liveFactory, null); + if (liveFactory is ILivePublishedModelFactory2 liveFactory2) + { + liveFactory2.Reset(); + } + else + { + // This is purely here for backwards compat and to avoid breaking changes but this code will probably never get executed + var resetMethod = liveFactory.GetType().GetMethod("ResetModels", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + if (resetMethod != null) + resetMethod.Invoke(liveFactory, null); + } action(); } diff --git a/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs b/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs index 8e8a19c729..b642f93bc9 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs @@ -21,7 +21,7 @@ using File = System.IO.File; namespace Umbraco.ModelsBuilder.Embedded { - internal class PureLiveModelFactory : ILivePublishedModelFactory, IRegisteredObject + internal class PureLiveModelFactory : ILivePublishedModelFactory2, IRegisteredObject { private Assembly _modelsAssembly; private Infos _infos = new Infos { ModelInfos = null, ModelTypeMap = new Dictionary() }; @@ -134,6 +134,13 @@ namespace Umbraco.ModelsBuilder.Embedded return ctor(); } + /// + public void Reset() + { + if (_config.Enable) + ResetModels(); + } + #endregion #region Compilation From 44df0dda2b8bfe26bf2dafc5100381d4d141ecf2 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 20 Apr 2020 22:45:12 +1000 Subject: [PATCH 2/4] adding an event --- .../NuCache/PublishedSnapshotService.cs | 2 ++ .../PublishedSnapshotServiceBase.cs | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs index a33d9ee427..b6d77dd3a0 100755 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs @@ -858,6 +858,8 @@ namespace Umbraco.Web.PublishedCache.NuCache Notify(_contentStore, payloads, RefreshContentTypesLocked); Notify(_mediaStore, payloads, RefreshMediaTypesLocked); + OnNotified(new NotifiedEventArgs(payloads)); + if (_publishedModelFactory.IsLiveFactory()) { //In the case of Pure Live - we actually need to refresh all of the content and the media diff --git a/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs b/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs index 20d3e6d8e3..f40b3d10c2 100644 --- a/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs +++ b/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs @@ -1,11 +1,22 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Umbraco.Core.Models.Membership; using Umbraco.Core.Models.PublishedContent; using Umbraco.Web.Cache; namespace Umbraco.Web.PublishedCache { - abstract class PublishedSnapshotServiceBase : IPublishedSnapshotService + internal class NotifiedEventArgs : EventArgs + { + public NotifiedEventArgs(T[] payloads) + { + Payloads = payloads; + } + + public T[] Payloads { get; } + } + + internal abstract class PublishedSnapshotServiceBase : IPublishedSnapshotService { protected PublishedSnapshotServiceBase(IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor) { @@ -38,5 +49,8 @@ namespace Umbraco.Web.PublishedCache public virtual void Dispose() { } + + protected void OnNotified(NotifiedEventArgs args) => Notified?.Invoke(this, args); + public event EventHandler> Notified; } } From e62fef8fafa12e93c5047395322c8d8b78fb287c Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 20 Apr 2020 23:22:03 +1000 Subject: [PATCH 3/4] Ensures entire nucache linked list is not rebuild on schema changes when disabled --- .../ILivePublishedModelFactory.cs | 5 +++++ .../PublishedModelFactoryExtensions.cs | 15 ++++++++++++++- .../PureLiveModelFactory.cs | 3 +++ .../NuCache/PublishedSnapshotService.cs | 4 +--- .../PublishedSnapshotServiceBase.cs | 3 --- 5 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Core/Models/PublishedContent/ILivePublishedModelFactory.cs b/src/Umbraco.Core/Models/PublishedContent/ILivePublishedModelFactory.cs index 0d7744389a..39b9f038be 100644 --- a/src/Umbraco.Core/Models/PublishedContent/ILivePublishedModelFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/ILivePublishedModelFactory.cs @@ -9,6 +9,11 @@ /// Tells the factory that it should build a new generation of models /// void Reset(); + + /// + /// If the live model factory + /// + bool Enabled { get; } } /// diff --git a/src/Umbraco.Core/PublishedModelFactoryExtensions.cs b/src/Umbraco.Core/PublishedModelFactoryExtensions.cs index cfb29038c6..697e3fd11f 100644 --- a/src/Umbraco.Core/PublishedModelFactoryExtensions.cs +++ b/src/Umbraco.Core/PublishedModelFactoryExtensions.cs @@ -17,6 +17,20 @@ namespace Umbraco.Core /// public static bool IsLiveFactory(this IPublishedModelFactory factory) => factory is ILivePublishedModelFactory; + /// + /// Returns true if the current is an implementation of and is enabled + /// + /// + /// + public static bool IsLiveFactoryEnabled(this IPublishedModelFactory factory) + { + if (factory is ILivePublishedModelFactory2 liveFactory2) + return liveFactory2.Enabled; + + // if it's not ILivePublishedModelFactory2 we can't determine if it's enabled or not so return true + return factory is ILivePublishedModelFactory; + } + [Obsolete("This method is no longer used or necessary and will be removed from future")] [EditorBrowsable(EditorBrowsableState.Never)] public static void WithSafeLiveFactory(this IPublishedModelFactory factory, Action action) @@ -61,7 +75,6 @@ namespace Umbraco.Core if (resetMethod != null) resetMethod.Invoke(liveFactory, null); } - action(); } } diff --git a/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs b/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs index b642f93bc9..0e125759c6 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs @@ -134,6 +134,9 @@ namespace Umbraco.ModelsBuilder.Embedded return ctor(); } + /// + public bool Enabled => _config.Enable; + /// public void Reset() { diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs index 1fc738b737..7e78b2e96f 100755 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs @@ -859,9 +859,7 @@ namespace Umbraco.Web.PublishedCache.NuCache Notify(_contentStore, payloads, RefreshContentTypesLocked); Notify(_mediaStore, payloads, RefreshMediaTypesLocked); - OnNotified(new NotifiedEventArgs(payloads)); - - if (_publishedModelFactory.IsLiveFactory()) + if (_publishedModelFactory.IsLiveFactoryEnabled()) { //In the case of Pure Live - we actually need to refresh all of the content and the media //see https://github.com/umbraco/Umbraco-CMS/issues/5671 diff --git a/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs b/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs index f40b3d10c2..3ebb0fd289 100644 --- a/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs +++ b/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs @@ -49,8 +49,5 @@ namespace Umbraco.Web.PublishedCache public virtual void Dispose() { } - - protected void OnNotified(NotifiedEventArgs args) => Notified?.Invoke(this, args); - public event EventHandler> Notified; } } From 279329d68230745bfec2390b24117b6f56537a36 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 29 Apr 2020 10:32:05 +1000 Subject: [PATCH 4/4] removes code that shouldn't have been committed. --- .../PublishedCache/PublishedSnapshotServiceBase.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs b/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs index 3ebb0fd289..1b56f54569 100644 --- a/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs +++ b/src/Umbraco.Web/PublishedCache/PublishedSnapshotServiceBase.cs @@ -6,16 +6,6 @@ using Umbraco.Web.Cache; namespace Umbraco.Web.PublishedCache { - internal class NotifiedEventArgs : EventArgs - { - public NotifiedEventArgs(T[] payloads) - { - Payloads = payloads; - } - - public T[] Payloads { get; } - } - internal abstract class PublishedSnapshotServiceBase : IPublishedSnapshotService { protected PublishedSnapshotServiceBase(IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor)