Skip to content

Commit

Permalink
V15: Reimplement cache startup handler (#17279)
Browse files Browse the repository at this point in the history
* Reimplement cache startup handler

* Remove duplicate handle

* Fixed missing scope and ordering of notifications

* formatting

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
  • Loading branch information
Zeegaan and bergmania authored Oct 15, 2024
1 parent 25be93b commit fc0e62f
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/Umbraco.Core/PublishedCache/IDatabaseCacheRebuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@
public interface IDatabaseCacheRebuilder
{
void Rebuild();

void RebuildDatabaseCacheIfSerializerChanged();
}
47 changes: 45 additions & 2 deletions src/Umbraco.PublishedCache.HybridCache/DatabaseCacheRebuilder.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,37 @@
using Umbraco.Cms.Core.PublishedCache;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Logging;
using Umbraco.Cms.Core.PublishedCache;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.HybridCache.Persistence;

namespace Umbraco.Cms.Infrastructure.HybridCache;

internal class DatabaseCacheRebuilder : IDatabaseCacheRebuilder
{
private const string NuCacheSerializerKey = "Umbraco.Web.PublishedCache.NuCache.Serializer";
private readonly IDatabaseCacheRepository _databaseCacheRepository;
private readonly ICoreScopeProvider _coreScopeProvider;
private readonly IOptions<NuCacheSettings> _nucacheSettings;
private readonly IKeyValueService _keyValueService;
private readonly ILogger<DatabaseCacheRebuilder> _logger;
private readonly IProfilingLogger _profilingLogger;

public DatabaseCacheRebuilder(IDatabaseCacheRepository databaseCacheRepository, ICoreScopeProvider coreScopeProvider)
public DatabaseCacheRebuilder(
IDatabaseCacheRepository databaseCacheRepository,
ICoreScopeProvider coreScopeProvider,
IOptions<NuCacheSettings> nucacheSettings,
IKeyValueService keyValueService,
ILogger<DatabaseCacheRebuilder> logger, IProfilingLogger profilingLogger)
{
_databaseCacheRepository = databaseCacheRepository;
_coreScopeProvider = coreScopeProvider;
_nucacheSettings = nucacheSettings;
_keyValueService = keyValueService;
_logger = logger;
_profilingLogger = profilingLogger;
}

public void Rebuild()
Expand All @@ -21,4 +40,28 @@ public void Rebuild()
_databaseCacheRepository.Rebuild();
scope.Complete();
}

public void RebuildDatabaseCacheIfSerializerChanged()
{
using var scope = _coreScopeProvider.CreateCoreScope();
NuCacheSerializerType serializer = _nucacheSettings.Value.NuCacheSerializerType;
var currentSerializerValue = _keyValueService.GetValue(NuCacheSerializerKey);

if (Enum.TryParse(currentSerializerValue, out NuCacheSerializerType currentSerializer) && serializer == currentSerializer)
{
return;
}

_logger.LogWarning(
"Database cache was serialized using {CurrentSerializer}. Currently configured cache serializer {Serializer}. Rebuilding database cache.",
currentSerializer, serializer);

using (_profilingLogger.TraceDuration<DatabaseCacheRebuilder>($"Rebuilding database cache with {serializer} serializer"))
{
Rebuild();
_keyValueService.SetValue(NuCacheSerializerKey, serializer.ToString());
}

scope.Complete();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public static IUmbracoBuilder AddUmbracoHybridCache(this IUmbracoBuilder builder
throw new IndexOutOfRangeException();
}
});
builder.AddNotificationAsyncHandler<UmbracoApplicationStartingNotification, HybridCacheStartupNotificationHandler>(); // Need to happen before notification handlers use the cache. Eg. seeding
builder.Services.AddSingleton<IPropertyCacheCompressionOptions, NoopPropertyCacheCompressionOptions>();
builder.AddNotificationAsyncHandler<ContentRefreshNotification, CacheRefreshingNotificationHandler>();
builder.AddNotificationAsyncHandler<ContentDeletedNotification, CacheRefreshingNotificationHandler>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.PublishedCache;
using Umbraco.Cms.Core.Services;

namespace Umbraco.Cms.Infrastructure.HybridCache.NotificationHandlers;

/// <summary>
/// Rebuilds the database cache if required when the serializer changes
/// </summary>
public class HybridCacheStartupNotificationHandler : INotificationAsyncHandler<UmbracoApplicationStartingNotification>
{
private readonly IDatabaseCacheRebuilder _databaseCacheRebuilder;
private readonly IRuntimeState _runtimeState;

public HybridCacheStartupNotificationHandler(IDatabaseCacheRebuilder databaseCacheRebuilder, IRuntimeState runtimeState)
{
_databaseCacheRebuilder = databaseCacheRebuilder;
_runtimeState = runtimeState;
}

public Task HandleAsync(UmbracoApplicationStartingNotification notification, CancellationToken cancellationToken)
{
if (_runtimeState.Level > RuntimeLevel.Install)
{
_databaseCacheRebuilder.RebuildDatabaseCacheIfSerializerChanged();
}

return Task.CompletedTask;
}
}

0 comments on commit fc0e62f

Please sign in to comment.