From 928537dcfc2c2fed5f362acad7d1ddac74ff1ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kriszti=C3=A1n=20N=C3=A9meth?= Date: Fri, 25 Nov 2022 20:36:29 +0100 Subject: [PATCH 1/3] Adding media theme templates memory cache --- .../Services/IMediaThemeCachingService.cs | 22 ++++++++++ .../Services/MediaThemeCachingService.cs | 41 +++++++++++++++++++ Lombiq.Hosting.MediaTheme.Bridge/Startup.cs | 1 + 3 files changed, 64 insertions(+) create mode 100644 Lombiq.Hosting.MediaTheme.Bridge/Services/IMediaThemeCachingService.cs create mode 100644 Lombiq.Hosting.MediaTheme.Bridge/Services/MediaThemeCachingService.cs diff --git a/Lombiq.Hosting.MediaTheme.Bridge/Services/IMediaThemeCachingService.cs b/Lombiq.Hosting.MediaTheme.Bridge/Services/IMediaThemeCachingService.cs new file mode 100644 index 0000000..71ab89a --- /dev/null +++ b/Lombiq.Hosting.MediaTheme.Bridge/Services/IMediaThemeCachingService.cs @@ -0,0 +1,22 @@ +using Lombiq.Hosting.MediaTheme.Bridge.Models; +using System.Threading.Tasks; + +namespace Lombiq.Hosting.MediaTheme.Bridge.Services; + +/// +/// Media Theme template cache store and invalidation functions. +/// +public interface IMediaThemeCachingService +{ + /// + /// Returns if cached, else tries to fetch it from the storage. If not available stores + /// and returns . + /// + /// The searched shape type. + Task GetMemoryCachedMediaTemplateAsync(string shapeType); + + /// + /// Deletes all Media Theme templates from the cache. + /// + Task InvalidateCachedMediaThemeTemplatesAsync(); +} diff --git a/Lombiq.Hosting.MediaTheme.Bridge/Services/MediaThemeCachingService.cs b/Lombiq.Hosting.MediaTheme.Bridge/Services/MediaThemeCachingService.cs new file mode 100644 index 0000000..a7d099e --- /dev/null +++ b/Lombiq.Hosting.MediaTheme.Bridge/Services/MediaThemeCachingService.cs @@ -0,0 +1,41 @@ +using Lombiq.Hosting.MediaTheme.Bridge.Models; +using Microsoft.Extensions.Caching.Memory; +using OrchardCore.Environment.Cache; +using System.Threading.Tasks; + +namespace Lombiq.Hosting.MediaTheme.Bridge.Services; + +public class MediaThemeCachingService : IMediaThemeCachingService +{ + private const string MediaThemeMemoryCacheKeyPrefix = "Lombiq.Hosting.MediaTheme.Bridge"; + + private readonly IMemoryCache _memoryCache; + private readonly IMediaThemeManager _mediaThemeManager; + private readonly ISignal _signal; + + public MediaThemeCachingService( + IMemoryCache memoryCache, + IMediaThemeManager mediaThemeManager, + ISignal signal) + { + _memoryCache = memoryCache; + _mediaThemeManager = mediaThemeManager; + _signal = signal; + } + + public async Task GetMemoryCachedMediaTemplateAsync(string shapeType) + { + var cacheKey = $"{MediaThemeMemoryCacheKeyPrefix}:{shapeType}"; + if (_memoryCache.TryGetValue(cacheKey, out MediaTemplate cachedMediaTemplate)) + { + return cachedMediaTemplate; + } + + cachedMediaTemplate = await _mediaThemeManager.GetMediaTemplateByShapeTypeAsync(shapeType); + _memoryCache.Set(cacheKey, cachedMediaTemplate, _signal.GetToken(MediaThemeMemoryCacheKeyPrefix)); + + return cachedMediaTemplate; + } + + public Task InvalidateCachedMediaThemeTemplatesAsync() => _signal.SignalTokenAsync(MediaThemeMemoryCacheKeyPrefix); +} diff --git a/Lombiq.Hosting.MediaTheme.Bridge/Startup.cs b/Lombiq.Hosting.MediaTheme.Bridge/Startup.cs index 7dc6018..1a48291 100644 --- a/Lombiq.Hosting.MediaTheme.Bridge/Startup.cs +++ b/Lombiq.Hosting.MediaTheme.Bridge/Startup.cs @@ -37,6 +37,7 @@ public override void ConfigureServices(IServiceCollection services) services.AddSingleton(new DeploymentStepFactory()); services.AddScoped, MediaThemeDeploymentStepDriver>(); services.AddScoped(); + services.AddScoped(); } public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) From 5110ba204fc93a59b2abc3301ca7b641ade84b71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kriszti=C3=A1n=20N=C3=A9meth?= Date: Fri, 25 Nov 2022 20:36:44 +0100 Subject: [PATCH 2/3] Using new memory cache service for the resolver --- .../Services/MediaTemplatesShapeBindingResolver.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Bridge/Services/MediaTemplatesShapeBindingResolver.cs b/Lombiq.Hosting.MediaTheme.Bridge/Services/MediaTemplatesShapeBindingResolver.cs index 419fd19..3447529 100644 --- a/Lombiq.Hosting.MediaTheme.Bridge/Services/MediaTemplatesShapeBindingResolver.cs +++ b/Lombiq.Hosting.MediaTheme.Bridge/Services/MediaTemplatesShapeBindingResolver.cs @@ -13,18 +13,18 @@ public class MediaTemplatesShapeBindingResolver : IShapeBindingResolver private readonly ILiquidTemplateManager _liquidTemplateManager; private readonly IHttpContextAccessor _hca; private readonly HtmlEncoder _htmlEncoder; - private readonly IMediaThemeManager _mediaThemeManager; + private readonly IMediaThemeCachingService _mediaThemeCachingService; public MediaTemplatesShapeBindingResolver( ILiquidTemplateManager liquidTemplateManager, IHttpContextAccessor hca, HtmlEncoder htmlEncoder, - IMediaThemeManager mediaThemeManager) + IMediaThemeCachingService mediaThemeCachingService) { _liquidTemplateManager = liquidTemplateManager; _hca = hca; _htmlEncoder = htmlEncoder; - _mediaThemeManager = mediaThemeManager; + _mediaThemeCachingService = mediaThemeCachingService; } public async Task GetShapeBindingAsync(string shapeType) @@ -34,7 +34,7 @@ public async Task GetShapeBindingAsync(string shapeType) return null; } - return await _mediaThemeManager.GetMediaTemplateByShapeTypeAsync(shapeType) is not { } mediaTemplate + return await _mediaThemeCachingService.GetMemoryCachedMediaTemplateAsync(shapeType) is not { } mediaTemplate ? null : BuildShapeBinding(shapeType, mediaTemplate.Content); } From e3ad812e8fcbe7da8bc9e468db9a5b1ec03109db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kriszti=C3=A1n=20N=C3=A9meth?= Date: Fri, 25 Nov 2022 20:37:26 +0100 Subject: [PATCH 3/3] Adding cache invalidation button on media theme settings page. --- .../Controllers/AdminController.cs | 33 +++++++++++++++---- .../Views/Admin/Index.cshtml | 7 ++++ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Bridge/Controllers/AdminController.cs b/Lombiq.Hosting.MediaTheme.Bridge/Controllers/AdminController.cs index 5f8b724..4ad32de 100644 --- a/Lombiq.Hosting.MediaTheme.Bridge/Controllers/AdminController.cs +++ b/Lombiq.Hosting.MediaTheme.Bridge/Controllers/AdminController.cs @@ -1,10 +1,13 @@ -using Lombiq.Hosting.MediaTheme.Bridge.Constants; +using Lombiq.HelpfulLibraries.OrchardCore.DependencyInjection; +using Lombiq.Hosting.MediaTheme.Bridge.Constants; using Lombiq.Hosting.MediaTheme.Bridge.Services; using Lombiq.Hosting.MediaTheme.Bridge.ViewModels; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Localization; using Microsoft.Extensions.Localization; using OrchardCore.DisplayManagement.ModelBinding; +using OrchardCore.DisplayManagement.Notify; using OrchardCore.Themes.Services; using System.Linq; using System.Threading.Tasks; @@ -18,23 +21,30 @@ public class AdminController : Controller private readonly IMediaThemeStateStore _mediaThemeStateStore; private readonly IUpdateModelAccessor _updateModelAccessor; private readonly IStringLocalizer T; + private readonly IHtmlLocalizer H; private readonly IMediaThemeManager _mediaThemeManager; private readonly ISiteThemeService _siteThemeService; + private readonly IMediaThemeCachingService _mediaThemeCachingService; + private readonly INotifier _notifier; public AdminController( - IAuthorizationService authorizationService, + IOrchardServices orchardServices, IMediaThemeStateStore mediaThemeStateStore, IUpdateModelAccessor updateModelAccessor, - IStringLocalizer stringLocalizer, IMediaThemeManager mediaThemeManager, - ISiteThemeService siteThemeService) + ISiteThemeService siteThemeService, + IMediaThemeCachingService mediaThemeCachingService, + INotifier notifier) { - _authorizationService = authorizationService; + _authorizationService = orchardServices.AuthorizationService.Value; _mediaThemeStateStore = mediaThemeStateStore; _updateModelAccessor = updateModelAccessor; - T = stringLocalizer; + T = orchardServices.StringLocalizer.Value; _mediaThemeManager = mediaThemeManager; _siteThemeService = siteThemeService; + _mediaThemeCachingService = mediaThemeCachingService; + _notifier = notifier; + H = orchardServices.HtmlLocalizer.Value; } [HttpGet] @@ -78,6 +88,17 @@ public async Task IndexPost(MediaThemeSettingsViewModel viewModel) return RedirectToAction(nameof(Index)); } + [HttpPost] + [ValidateAntiForgeryToken] + public async Task DeleteMediaThemeTemplateCache() + { + if (!await IsAuthorizedToManageMediaThemeAsync()) return NotFound(); + + await _mediaThemeCachingService.InvalidateCachedMediaThemeTemplatesAsync(); + await _notifier.SuccessAsync(H["Media Theme template cache was invalidated successfully!"]); + return RedirectToAction(nameof(Index)); + } + private Task IsAuthorizedToManageMediaThemeAsync() => _authorizationService.AuthorizeAsync(User, ManageMediaTheme); diff --git a/Lombiq.Hosting.MediaTheme.Bridge/Views/Admin/Index.cshtml b/Lombiq.Hosting.MediaTheme.Bridge/Views/Admin/Index.cshtml index 80ad143..56d92dd 100644 --- a/Lombiq.Hosting.MediaTheme.Bridge/Views/Admin/Index.cshtml +++ b/Lombiq.Hosting.MediaTheme.Bridge/Views/Admin/Index.cshtml @@ -47,3 +47,10 @@ + +
+ @Html.ValidationSummary() +
+ +
+