From ae54cb9947773a682d4992003dff8a27532202fa Mon Sep 17 00:00:00 2001 From: Chad Date: Wed, 4 May 2022 07:35:33 +1200 Subject: [PATCH] v10: Improve redirect content finder scalability (#12341) * Async support for content finders. Improve log performance. * Improve redirect contentfinder scalablilty with async calls to the database --- .../Repositories/IRedirectUrlRepository.cs | 18 ++++++- .../Routing/ContentFinderByRedirectUrl.cs | 2 +- .../Services/IRedirectUrlService.cs | 11 ++++- .../Services/RedirectUrlService.cs | 23 ++++++++- .../Implement/RedirectUrlRepository.cs | 49 +++++++++++++++++-- 5 files changed, 95 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/IRedirectUrlRepository.cs b/src/Umbraco.Core/Persistence/Repositories/IRedirectUrlRepository.cs index 17be5b3856..0c2e4235ee 100644 --- a/src/Umbraco.Core/Persistence/Repositories/IRedirectUrlRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/IRedirectUrlRepository.cs @@ -1,5 +1,6 @@ -using System; +using System; using System.Collections.Generic; +using System.Threading.Tasks; using Umbraco.Cms.Core.Models; namespace Umbraco.Cms.Core.Persistence.Repositories @@ -42,6 +43,13 @@ namespace Umbraco.Cms.Core.Persistence.Repositories /// The most recent redirect URL corresponding to the route. IRedirectUrl? GetMostRecentUrl(string url); + /// + /// Gets the most recent redirect URL corresponding to an Umbraco redirect URL route. + /// + /// The Umbraco redirect URL route. + /// The most recent redirect URL corresponding to the route. + Task GetMostRecentUrlAsync(string url); + /// /// Gets the most recent redirect URL corresponding to an Umbraco redirect URL route. /// @@ -50,6 +58,14 @@ namespace Umbraco.Cms.Core.Persistence.Repositories /// The most recent redirect URL corresponding to the route. IRedirectUrl? GetMostRecentUrl(string url, string culture); + /// + /// Gets the most recent redirect URL corresponding to an Umbraco redirect URL route. + /// + /// The Umbraco redirect URL route. + /// The culture the domain is associated with + /// The most recent redirect URL corresponding to the route. + Task GetMostRecentUrlAsync(string url, string culture); + /// /// Gets all redirect URLs for a content item. /// diff --git a/src/Umbraco.Core/Routing/ContentFinderByRedirectUrl.cs b/src/Umbraco.Core/Routing/ContentFinderByRedirectUrl.cs index a200afec67..5b3d80f3ea 100644 --- a/src/Umbraco.Core/Routing/ContentFinderByRedirectUrl.cs +++ b/src/Umbraco.Core/Routing/ContentFinderByRedirectUrl.cs @@ -55,7 +55,7 @@ namespace Umbraco.Cms.Core.Routing ? frequest.Domain.ContentId + DomainUtilities.PathRelativeToDomain(frequest.Domain.Uri, frequest.AbsolutePathDecoded) : frequest.AbsolutePathDecoded; - IRedirectUrl? redirectUrl = _redirectUrlService.GetMostRecentRedirectUrl(route, frequest.Culture); + IRedirectUrl? redirectUrl = await _redirectUrlService.GetMostRecentRedirectUrlAsync(route, frequest.Culture); if (redirectUrl == null) { diff --git a/src/Umbraco.Core/Services/IRedirectUrlService.cs b/src/Umbraco.Core/Services/IRedirectUrlService.cs index 3c061db466..ddefb2e23e 100644 --- a/src/Umbraco.Core/Services/IRedirectUrlService.cs +++ b/src/Umbraco.Core/Services/IRedirectUrlService.cs @@ -1,5 +1,6 @@ -using System; +using System; using System.Collections.Generic; +using System.Threading.Tasks; using Umbraco.Cms.Core.Models; namespace Umbraco.Cms.Core.Services @@ -56,6 +57,14 @@ namespace Umbraco.Cms.Core.Services /// The most recent redirect URLs corresponding to the route. IRedirectUrl? GetMostRecentRedirectUrl(string url, string? culture); + /// + /// Gets the most recent redirect URLs corresponding to an Umbraco redirect URL route. + /// + /// The Umbraco redirect URL route. + /// The culture of the request. + /// The most recent redirect URLs corresponding to the route. + Task GetMostRecentRedirectUrlAsync(string url, string? culture); + /// /// Gets all redirect URLs for a content item. /// diff --git a/src/Umbraco.Core/Services/RedirectUrlService.cs b/src/Umbraco.Core/Services/RedirectUrlService.cs index 14c3e834bf..8fe8b02a46 100644 --- a/src/Umbraco.Core/Services/RedirectUrlService.cs +++ b/src/Umbraco.Core/Services/RedirectUrlService.cs @@ -1,5 +1,6 @@ -using System; +using System; using System.Collections.Generic; +using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; @@ -76,6 +77,13 @@ namespace Umbraco.Cms.Core.Services return _redirectUrlRepository.GetMostRecentUrl(url); } } + public async Task GetMostRecentRedirectUrlAsync(string url) + { + using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) + { + return await _redirectUrlRepository.GetMostRecentUrlAsync(url); + } + } public IEnumerable GetContentRedirectUrls(Guid contentKey) { @@ -118,5 +126,18 @@ namespace Umbraco.Cms.Core.Services } } + public async Task GetMostRecentRedirectUrlAsync(string url, string? culture) + { + if (string.IsNullOrWhiteSpace(culture)) + { + return await GetMostRecentRedirectUrlAsync(url); + } + + using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) + { + return await _redirectUrlRepository.GetMostRecentUrlAsync(url, culture); + } + + } } } diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/RedirectUrlRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/RedirectUrlRepository.cs index e49ccbdf77..52647983e0 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/RedirectUrlRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/RedirectUrlRepository.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; +using System.Threading.Tasks; using Microsoft.Extensions.Logging; using NPoco; using Umbraco.Cms.Core; @@ -40,14 +41,27 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement public void Delete(Guid id) => Database.Delete(id); public IRedirectUrl? GetMostRecentUrl(string url) + { + Sql sql = GetMostRecentSql(url); + List dtos = Database.Fetch(sql); + RedirectUrlDto? dto = dtos.FirstOrDefault(); + return dto == null ? null : Map(dto); + } + public async Task GetMostRecentUrlAsync(string url) + { + Sql sql = GetMostRecentSql(url); + List dtos = await Database.FetchAsync(sql); + RedirectUrlDto? dto = dtos.FirstOrDefault(); + return dto == null ? null : Map(dto); + } + + private Sql GetMostRecentSql(string url) { var urlHash = url.GenerateHash(); Sql sql = GetBaseQuery(false) .Where(x => x.Url == url && x.UrlHash == urlHash) .OrderByDescending(x => x.CreateDateUtc); - List dtos = Database.Fetch(sql); - RedirectUrlDto? dto = dtos.FirstOrDefault(); - return dto == null ? null : Map(dto); + return sql; } public IRedirectUrl? GetMostRecentUrl(string url, string culture) @@ -57,12 +71,39 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement return GetMostRecentUrl(url); } + Sql sql = GetMostRecentUrlSql(url, culture); + + List dtos = Database.Fetch(sql); + RedirectUrlDto? dto = dtos.FirstOrDefault(f => f.Culture == culture.ToLower()); + + if (dto == null) + { + dto = dtos.FirstOrDefault(f => string.IsNullOrWhiteSpace(f.Culture)); + } + + return dto == null ? null : Map(dto); + } + + private Sql GetMostRecentUrlSql(string url, string culture) + { var urlHash = url.GenerateHash(); Sql sql = GetBaseQuery(false) .Where(x => x.Url == url && x.UrlHash == urlHash && (x.Culture == culture.ToLower() || x.Culture == null || x.Culture == string.Empty)) .OrderByDescending(x => x.CreateDateUtc); - List dtos = Database.Fetch(sql); + return sql; + } + + public async Task GetMostRecentUrlAsync(string url, string culture) + { + if (string.IsNullOrWhiteSpace(culture)) + { + return GetMostRecentUrl(url); + } + + Sql sql = GetMostRecentUrlSql(url, culture); + + List dtos = await Database.FetchAsync(sql); RedirectUrlDto? dto = dtos.FirstOrDefault(f => f.Culture == culture.ToLower()); if (dto == null)