diff --git a/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs b/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs index 6fdd5c9be7..655867ebeb 100644 --- a/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs @@ -37,7 +37,6 @@ namespace Umbraco.Extensions // We need to add this before UseRouting so that the UmbracoContext and other middlewares are executed // before endpoint routing middleware. app.UseUmbracoRouting(); - app.UseUmbracoContentCache(); app.UseStatusCodePages(); @@ -178,18 +177,6 @@ namespace Umbraco.Extensions return app; } - /// - /// Enables the Umbraco content cache - /// - public static IApplicationBuilder UseUmbracoContentCache(this IApplicationBuilder app) - { - // TODO: This should install middleware to initialize instead of eagerly doing the initialize here - - PublishedSnapshotServiceEventHandler publishedContentEvents = app.ApplicationServices.GetRequiredService(); - publishedContentEvents.Start(); - return app; - } - /// /// Ensures the runtime is shutdown when the application is shutting down /// diff --git a/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs b/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs index 56f093ed2b..7845962928 100644 --- a/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs +++ b/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Extensions; @@ -8,6 +9,7 @@ using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Logging; using Umbraco.Web.Common.Lifetime; +using Umbraco.Web.PublishedCache.NuCache; namespace Umbraco.Web.Common.Middleware { @@ -16,7 +18,12 @@ namespace Umbraco.Web.Common.Middleware /// Manages Umbraco request objects and their lifetime /// /// + /// + /// This is responsible for initializing the content cache + /// + /// /// This is responsible for creating and assigning an + /// /// public class UmbracoRequestMiddleware : IMiddleware { @@ -25,6 +32,10 @@ namespace Umbraco.Web.Common.Middleware private readonly IUmbracoContextFactory _umbracoContextFactory; private readonly IRequestCache _requestCache; private readonly IBackOfficeSecurityFactory _backofficeSecurityFactory; + private readonly PublishedSnapshotServiceEventHandler _publishedSnapshotServiceEventHandler; + private static bool s_cacheInitialized = false; + private static bool s_cacheInitializedFlag = false; + private static object s_cacheInitializedLock = new object(); /// /// Initializes a new instance of the class. @@ -34,13 +45,15 @@ namespace Umbraco.Web.Common.Middleware IUmbracoRequestLifetimeManager umbracoRequestLifetimeManager, IUmbracoContextFactory umbracoContextFactory, IRequestCache requestCache, - IBackOfficeSecurityFactory backofficeSecurityFactory) + IBackOfficeSecurityFactory backofficeSecurityFactory, + PublishedSnapshotServiceEventHandler publishedSnapshotServiceEventHandler) { _logger = logger; _umbracoRequestLifetimeManager = umbracoRequestLifetimeManager; _umbracoContextFactory = umbracoContextFactory; _requestCache = requestCache; _backofficeSecurityFactory = backofficeSecurityFactory; + _publishedSnapshotServiceEventHandler = publishedSnapshotServiceEventHandler; } /// @@ -55,6 +68,8 @@ namespace Umbraco.Web.Common.Middleware return; } + EnsureContentCacheInitialized(); + _backofficeSecurityFactory.EnsureBackOfficeSecurity(); // Needs to be before UmbracoContext, TODO: Why? UmbracoContextReference umbracoContextReference = _umbracoContextFactory.EnsureUmbracoContext(); @@ -109,16 +124,15 @@ namespace Umbraco.Web.Common.Middleware /// /// Any object that is in the HttpContext.Items collection that is IDisposable will get disposed on the end of the request /// - /// - /// - /// private static void DisposeRequestCacheItems(ILogger logger, IRequestCache requestCache, Uri requestUri) { // do not process if client-side request if (requestUri.IsClientSideRequest()) + { return; + } - //get a list of keys to dispose + // get a list of keys to dispose var keys = new HashSet(); foreach (var i in requestCache) { @@ -127,7 +141,7 @@ namespace Umbraco.Web.Common.Middleware keys.Add(i.Key); } } - //dispose each item and key that was found as disposable. + // dispose each item and key that was found as disposable. foreach (var k in keys) { try @@ -149,6 +163,17 @@ namespace Umbraco.Web.Common.Middleware } } - + /// + /// Initializes the content cache one time + /// + private void EnsureContentCacheInitialized() => LazyInitializer.EnsureInitialized( + ref s_cacheInitialized, + ref s_cacheInitializedFlag, + ref s_cacheInitializedLock, + () => + { + _publishedSnapshotServiceEventHandler.Start(); + return true; + }); } }