From bea21d7b99a574a5d53a93eb4a712c3304e7f645 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Tue, 28 Oct 2025 13:25:13 +0100 Subject: [PATCH] Caching: Resolves publish and install issues related to stale cached data retrieval (closes #20539 and #20630) (#20640) * Request cache published content creation with version. * Reload memory cache after install with package migrations. * Improve message on install for database cache rebuild. * Update src/Umbraco.Infrastructure/Install/MigrationPlansExecutedNotificationHandler.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Relocated memory cache refresh after package install from notification handler to unattended upgrader. * Fix construtor breaking change --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: mole --- .../UmbracoBuilder.Installer.cs | 1 + .../Install/UnattendedUpgrader.cs | 45 ++++++++++++++++--- .../DatabaseCacheRebuilder.cs | 2 +- .../Factories/PublishedContentFactory.cs | 2 +- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Installer.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Installer.cs index a5cf808b2e..885b8b65b0 100644 --- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Installer.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Installer.cs @@ -20,6 +20,7 @@ public static partial class UmbracoBuilderExtensions // Add post migration notification handlers builder.AddNotificationHandler(); + return builder; } } diff --git a/src/Umbraco.Infrastructure/Install/UnattendedUpgrader.cs b/src/Umbraco.Infrastructure/Install/UnattendedUpgrader.cs index 54f550f232..11e7836e9e 100644 --- a/src/Umbraco.Infrastructure/Install/UnattendedUpgrader.cs +++ b/src/Umbraco.Infrastructure/Install/UnattendedUpgrader.cs @@ -1,6 +1,8 @@ using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.DependencyInjection; @@ -28,7 +30,10 @@ public class UnattendedUpgrader : INotificationAsyncHandler _logger; + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 19.")] public UnattendedUpgrader( IProfilingLogger profilingLogger, IUmbracoVersion umbracoVersion, @@ -36,13 +41,36 @@ public class UnattendedUpgrader : INotificationAsyncHandler unattendedSettings) + : this( + profilingLogger, + umbracoVersion, + databaseBuilder, + runtimeState, + packageMigrationRunner, + unattendedSettings, + StaticServiceProvider.Instance.GetRequiredService(), + StaticServiceProvider.Instance.GetRequiredService>()) { - _profilingLogger = profilingLogger ?? throw new ArgumentNullException(nameof(profilingLogger)); - _umbracoVersion = umbracoVersion ?? throw new ArgumentNullException(nameof(umbracoVersion)); - _databaseBuilder = databaseBuilder ?? throw new ArgumentNullException(nameof(databaseBuilder)); - _runtimeState = runtimeState ?? throw new ArgumentNullException(nameof(runtimeState)); + } + + public UnattendedUpgrader( + IProfilingLogger profilingLogger, + IUmbracoVersion umbracoVersion, + DatabaseBuilder databaseBuilder, + IRuntimeState runtimeState, + PackageMigrationRunner packageMigrationRunner, + IOptions unattendedSettings, + DistributedCache distributedCache, + ILogger logger) + { + _profilingLogger = profilingLogger; + _umbracoVersion = umbracoVersion; + _databaseBuilder = databaseBuilder; + _runtimeState = runtimeState; _packageMigrationRunner = packageMigrationRunner; _unattendedSettings = unattendedSettings.Value; + _distributedCache = distributedCache; + _logger = logger; } public async Task HandleAsync(RuntimeUnattendedUpgradeNotification notification, CancellationToken cancellationToken) @@ -109,8 +137,13 @@ public class UnattendedUpgrader : INotificationAsyncHandler($"Rebuilding database cache with {serializer} serializer")) diff --git a/src/Umbraco.PublishedCache.HybridCache/Factories/PublishedContentFactory.cs b/src/Umbraco.PublishedCache.HybridCache/Factories/PublishedContentFactory.cs index 68f4d8d80f..a22ce1d07d 100644 --- a/src/Umbraco.PublishedCache.HybridCache/Factories/PublishedContentFactory.cs +++ b/src/Umbraco.PublishedCache.HybridCache/Factories/PublishedContentFactory.cs @@ -38,7 +38,7 @@ internal sealed class PublishedContentFactory : IPublishedContentFactory /// public IPublishedContent? ToIPublishedContent(ContentCacheNode contentCacheNode, bool preview) { - var cacheKey = $"{nameof(PublishedContentFactory)}DocumentCache_{contentCacheNode.Id}_{preview}"; + var cacheKey = $"{nameof(PublishedContentFactory)}DocumentCache_{contentCacheNode.Id}_{preview}_{contentCacheNode.Data?.VersionDate.Ticks ?? 0}"; IPublishedContent? publishedContent = null; if (_appCaches.RequestCache.IsAvailable) {