Skip to content

Commit 0d2393d

Browse files
AndyButlandCopilotnikolajlauridsen
committed
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 <[email protected]> * Relocated memory cache refresh after package install from notification handler to unattended upgrader. * Fix construtor breaking change --------- Co-authored-by: Copilot <[email protected]> Co-authored-by: mole <[email protected]>
1 parent 3dc65c4 commit 0d2393d

File tree

4 files changed

+42
-8
lines changed

4 files changed

+42
-8
lines changed

src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Installer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ internal static IUmbracoBuilder AddInstaller(this IUmbracoBuilder builder)
2020

2121
// Add post migration notification handlers
2222
builder.AddNotificationHandler<UmbracoPlanExecutedNotification, ClearCsrfCookieHandler>();
23+
2324
return builder;
2425
}
2526
}

src/Umbraco.Infrastructure/Install/UnattendedUpgrader.cs

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using Microsoft.Extensions.DependencyInjection;
2+
using Microsoft.Extensions.Logging;
23
using Microsoft.Extensions.Options;
34
using Umbraco.Cms.Core;
5+
using Umbraco.Cms.Core.Cache;
46
using Umbraco.Cms.Core.Configuration;
57
using Umbraco.Cms.Core.Configuration.Models;
68
using Umbraco.Cms.Core.DependencyInjection;
@@ -28,21 +30,47 @@ public class UnattendedUpgrader : INotificationAsyncHandler<RuntimeUnattendedUpg
2830
private readonly IRuntimeState _runtimeState;
2931
private readonly IUmbracoVersion _umbracoVersion;
3032
private readonly UnattendedSettings _unattendedSettings;
33+
private readonly DistributedCache _distributedCache;
34+
private readonly ILogger<UnattendedUpgrader> _logger;
3135

36+
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 19.")]
3237
public UnattendedUpgrader(
3338
IProfilingLogger profilingLogger,
3439
IUmbracoVersion umbracoVersion,
3540
DatabaseBuilder databaseBuilder,
3641
IRuntimeState runtimeState,
3742
PackageMigrationRunner packageMigrationRunner,
3843
IOptions<UnattendedSettings> unattendedSettings)
44+
: this(
45+
profilingLogger,
46+
umbracoVersion,
47+
databaseBuilder,
48+
runtimeState,
49+
packageMigrationRunner,
50+
unattendedSettings,
51+
StaticServiceProvider.Instance.GetRequiredService<DistributedCache>(),
52+
StaticServiceProvider.Instance.GetRequiredService<ILogger<UnattendedUpgrader>>())
3953
{
40-
_profilingLogger = profilingLogger ?? throw new ArgumentNullException(nameof(profilingLogger));
41-
_umbracoVersion = umbracoVersion ?? throw new ArgumentNullException(nameof(umbracoVersion));
42-
_databaseBuilder = databaseBuilder ?? throw new ArgumentNullException(nameof(databaseBuilder));
43-
_runtimeState = runtimeState ?? throw new ArgumentNullException(nameof(runtimeState));
54+
}
55+
56+
public UnattendedUpgrader(
57+
IProfilingLogger profilingLogger,
58+
IUmbracoVersion umbracoVersion,
59+
DatabaseBuilder databaseBuilder,
60+
IRuntimeState runtimeState,
61+
PackageMigrationRunner packageMigrationRunner,
62+
IOptions<UnattendedSettings> unattendedSettings,
63+
DistributedCache distributedCache,
64+
ILogger<UnattendedUpgrader> logger)
65+
{
66+
_profilingLogger = profilingLogger;
67+
_umbracoVersion = umbracoVersion;
68+
_databaseBuilder = databaseBuilder;
69+
_runtimeState = runtimeState;
4470
_packageMigrationRunner = packageMigrationRunner;
4571
_unattendedSettings = unattendedSettings.Value;
72+
_distributedCache = distributedCache;
73+
_logger = logger;
4674
}
4775

4876
public async Task HandleAsync(RuntimeUnattendedUpgradeNotification notification, CancellationToken cancellationToken)
@@ -109,8 +137,13 @@ private async Task RunPackageMigrationsAsync(RuntimeUnattendedUpgradeNotificatio
109137
try
110138
{
111139
await _packageMigrationRunner.RunPackagePlansAsync(pendingMigrations);
112-
notification.UnattendedUpgradeResult = RuntimeUnattendedUpgradeNotification.UpgradeResult
113-
.PackageMigrationComplete;
140+
notification.UnattendedUpgradeResult = RuntimeUnattendedUpgradeNotification.UpgradeResult.PackageMigrationComplete;
141+
142+
// Migration plans may have changed published content, so refresh the distributed cache to ensure consistency on first request.
143+
_distributedCache.RefreshAllPublishedSnapshot();
144+
_logger.LogInformation(
145+
"Migration plans run: {Plans}. Triggered refresh of distributed published content cache.",
146+
string.Join(", ", pendingMigrations));
114147
}
115148
catch (Exception ex)
116149
{

src/Umbraco.PublishedCache.HybridCache/DatabaseCacheRebuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public async Task RebuildDatabaseCacheIfSerializerChangedAsync()
108108

109109
_logger.LogWarning(
110110
"Database cache was serialized using {CurrentSerializer}. Currently configured cache serializer {Serializer}. Rebuilding database cache.",
111-
currentSerializer,
111+
currentSerializer == 0 ? "None" : currentSerializer,
112112
serializer);
113113

114114
using (_profilingLogger.TraceDuration<DatabaseCacheRebuilder>($"Rebuilding database cache with {serializer} serializer"))

src/Umbraco.PublishedCache.HybridCache/Factories/PublishedContentFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public PublishedContentFactory(
3838
/// <inheritdoc/>
3939
public IPublishedContent? ToIPublishedContent(ContentCacheNode contentCacheNode, bool preview)
4040
{
41-
var cacheKey = $"{nameof(PublishedContentFactory)}DocumentCache_{contentCacheNode.Id}_{preview}";
41+
var cacheKey = $"{nameof(PublishedContentFactory)}DocumentCache_{contentCacheNode.Id}_{preview}_{contentCacheNode.Data?.VersionDate.Ticks ?? 0}";
4242
IPublishedContent? publishedContent = null;
4343
if (_appCaches.RequestCache.IsAvailable)
4444
{

0 commit comments

Comments
 (0)