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 <nikolajlauridsen@protonmail.ch>
This commit is contained in:
@@ -20,6 +20,7 @@ public static partial class UmbracoBuilderExtensions
|
||||
|
||||
// Add post migration notification handlers
|
||||
builder.AddNotificationHandler<UmbracoPlanExecutedNotification, ClearCsrfCookieHandler>();
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<RuntimeUnattendedUpg
|
||||
private readonly IRuntimeState _runtimeState;
|
||||
private readonly IUmbracoVersion _umbracoVersion;
|
||||
private readonly UnattendedSettings _unattendedSettings;
|
||||
private readonly DistributedCache _distributedCache;
|
||||
private readonly ILogger<UnattendedUpgrader> _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<RuntimeUnattendedUpg
|
||||
IRuntimeState runtimeState,
|
||||
PackageMigrationRunner packageMigrationRunner,
|
||||
IOptions<UnattendedSettings> unattendedSettings)
|
||||
: this(
|
||||
profilingLogger,
|
||||
umbracoVersion,
|
||||
databaseBuilder,
|
||||
runtimeState,
|
||||
packageMigrationRunner,
|
||||
unattendedSettings,
|
||||
StaticServiceProvider.Instance.GetRequiredService<DistributedCache>(),
|
||||
StaticServiceProvider.Instance.GetRequiredService<ILogger<UnattendedUpgrader>>())
|
||||
{
|
||||
_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> unattendedSettings,
|
||||
DistributedCache distributedCache,
|
||||
ILogger<UnattendedUpgrader> 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<RuntimeUnattendedUpg
|
||||
try
|
||||
{
|
||||
await _packageMigrationRunner.RunPackagePlansAsync(pendingMigrations);
|
||||
notification.UnattendedUpgradeResult = RuntimeUnattendedUpgradeNotification.UpgradeResult
|
||||
.PackageMigrationComplete;
|
||||
notification.UnattendedUpgradeResult = RuntimeUnattendedUpgradeNotification.UpgradeResult.PackageMigrationComplete;
|
||||
|
||||
// Migration plans may have changed published content, so refresh the distributed cache to ensure consistency on first request.
|
||||
_distributedCache.RefreshAllPublishedSnapshot();
|
||||
_logger.LogInformation(
|
||||
"Migration plans run: {Plans}. Triggered refresh of distributed published content cache.",
|
||||
string.Join(", ", pendingMigrations));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -104,7 +104,7 @@ internal sealed class DatabaseCacheRebuilder : IDatabaseCacheRebuilder
|
||||
|
||||
_logger.LogWarning(
|
||||
"Database cache was serialized using {CurrentSerializer}. Currently configured cache serializer {Serializer}. Rebuilding database cache.",
|
||||
currentSerializer,
|
||||
currentSerializer == 0 ? "None" : currentSerializer,
|
||||
serializer);
|
||||
|
||||
using (_profilingLogger.TraceDuration<DatabaseCacheRebuilder>($"Rebuilding database cache with {serializer} serializer"))
|
||||
|
||||
@@ -39,7 +39,7 @@ internal sealed class PublishedContentFactory : IPublishedContentFactory
|
||||
/// <inheritdoc/>
|
||||
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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user