diff --git a/PARR.DAL/DomainServices/Shortcodes/Models/CachedGroupedShortCode.cs b/PARR.DAL/DomainServices/Shortcodes/Models/CachedGroupedShortCode.cs deleted file mode 100644 index 6d9e244d..00000000 --- a/PARR.DAL/DomainServices/Shortcodes/Models/CachedGroupedShortCode.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace PARR.DAL.DomainServices.Shortcodes.Models -{ - internal class CachedGroupedShortCode - { - public string Value { get; set; } = string.Empty; - public DateTimeOffset Timestamp { get; set; } - public string? Source { get; set; } = "ShortcodesService"; - public int Version { get; set; } = 1; - } -} diff --git a/PARR.DAL/DomainServices/Shortcodes/ShortcodesService.cs b/PARR.DAL/DomainServices/Shortcodes/ShortcodesService.cs index 53e8223a..bda65659 100644 --- a/PARR.DAL/DomainServices/Shortcodes/ShortcodesService.cs +++ b/PARR.DAL/DomainServices/Shortcodes/ShortcodesService.cs @@ -3,13 +3,13 @@ using Microsoft.Extensions.Logging; using PARR.Core.Common.Interfaces; using PARR.DAL.Contracts; using PARR.DAL.DomainModels; -using PARR.DAL.DomainServices.Shortcodes.Models; using PARR.DAL.DomainServices.UnitFilterService; using PARR.DAL.Models; using PARR.DAL.Models.Job; using PARR.DAL.Services.Interfaces; using PARR.DAL.Services.Interfaces.Job; using PARR.DAL.Services.Interfaces.Unit; +using PARR.Domain.Cache.Models; using PARR.Domain.Common.Template; using PARR.Domain.Enums; using System.Runtime.CompilerServices; @@ -130,6 +130,19 @@ namespace PARR.DAL.DomainServices.Shortcodes var callerName = caller ?? "Unknown"; + // Ключ: shortcodes_result_{TemplateIdN}_{Hash(str)} + var cacheKey = cacheService.GetKey( + new[] { "shortcodes", "result", template.Id.ToString("N") }, + new[] { str } + ); + + var cachedResult = await cacheService.GetCachedDataAsync(cacheKey).ConfigureAwait(false); + if (cachedResult != null) + { + logger.LogDebug("[{Caller}] Кэш попал для шаблона {TemplateId}", callerName, template.Id); + return cachedResult.Data.Result; + } + logger.LogDebug("[{Caller}] Начата подстановка шорткодов. Вход: '{Input}', templateId={TemplateId}", callerName, str, template.Id); var result = str; @@ -140,19 +153,29 @@ namespace PARR.DAL.DomainServices.Shortcodes var shortcodes = GetShortCodes(result).Select(m => m.Value).ToList(); if (!shortcodes.Any()) break; - // Подготавливаем данные с догрузкой при необходимости var data = await PrepareTemplateDataAsync(template, shortcodes, callerName).ConfigureAwait(false); - var oldResult = result; - // Подстановка всех типов шорткодов result = await ApplyAllShortcodesOnceAsync(result, data, shortcodes, callerName).ConfigureAwait(false); - iteration++; if (result == oldResult) break; } + // Сохранение в кэш (только если были изменения) + if (!string.IsNullOrEmpty(result) && result != str) + { + var toCache = new ShortcodesResult + { + Data = new ShortcodesResultDto { Result = result }, + Timestamp = DateTimeOffset.UtcNow, + Source = typeof(ShortcodesService).Name + }; + + await cacheService.SetCachedDataAsync(cacheKey, toCache, TimeSpan.FromMinutes(15)).ConfigureAwait(false); + logger.LogDebug("[{Caller}] Результат сохранён в кэш для ключа '{Key}'", callerName, cacheKey); + } + logger.LogDebug("[{Caller}] Подстановка завершена. Результат: '{Result}'", callerName, result); return result; } @@ -772,11 +795,11 @@ namespace PARR.DAL.DomainServices.Shortcodes //var cacheKey = $"gr_shcd_{jobGroupId:N}_{unitId:N}_{ComputeHash(fullShortcode)}"; var cacheKey = cacheService.GetKey(new[] { "grouped", "shortcode", $"{jobGroupId:N}", $"{unitId:N}" }, new[] { fullShortcode }); - var cachedData = await cacheService.GetCachedDataAsync(cacheKey).ConfigureAwait(false); + var cachedData = await cacheService.GetCachedDataAsync(cacheKey).ConfigureAwait(false); if (cachedData != null) { - logger.LogDebug("[{Caller}] Кэш попал для GroupedShortCode '{Name}': {Value}", caller, fullShortcode, cachedData.Value); - return cachedData.Value; + logger.LogDebug("[{Caller}] Кэш попал для GroupedShortCode '{Name}': {Value}", caller, fullShortcode, cachedData.Data.Value); + return cachedData.Data.Value; } logger.LogDebug("[{Caller}] Кэш промахнут для GroupedShortCode '{Name}'. Запрашиваем из БД.", caller, fullShortcode); @@ -793,14 +816,12 @@ namespace PARR.DAL.DomainServices.Shortcodes // Не кэшируем пустые значения if (!string.IsNullOrEmpty(mostFrequentValue)) { - var toCache = new CachedGroupedShortCode + var toCache = new GroupedShortcode { - Value = mostFrequentValue, + Data = new GroupedShortcodeDto { Value = mostFrequentValue }, Timestamp = DateTimeOffset.UtcNow, - Source = typeof(ShortcodesService).Name, - Version = 1 + Source = typeof(ShortcodesService).Name }; - await cacheService.SetCachedDataAsync(cacheKey, toCache, TimeSpan.FromHours(1)).ConfigureAwait(false); return mostFrequentValue; } diff --git a/PARR.Domain/Cache/Models/GroupedShortсode.cs b/PARR.Domain/Cache/Models/GroupedShortсode.cs new file mode 100644 index 00000000..109b7f2b --- /dev/null +++ b/PARR.Domain/Cache/Models/GroupedShortсode.cs @@ -0,0 +1,21 @@ +using PARR.Domain.Cache.Models.Base; + +namespace PARR.Domain.Cache.Models +{ + /// + /// Модель кэша для шорткодов группированных работ + /// + public class GroupedShortcode : IBaseCache + { + public required GroupedShortcodeDto Data { get; set; } + + public DateTimeOffset Timestamp { get; set; } + + public required string Source { get; set; } + } + + public class GroupedShortcodeDto + { + public required string Value { get; set; } + } +} diff --git a/PARR.Domain/Cache/Models/ShortcodesResult.cs b/PARR.Domain/Cache/Models/ShortcodesResult.cs new file mode 100644 index 00000000..643c8e11 --- /dev/null +++ b/PARR.Domain/Cache/Models/ShortcodesResult.cs @@ -0,0 +1,21 @@ +using PARR.Domain.Cache.Models.Base; + +namespace PARR.Domain.Cache.Models +{ + /// + /// Модель кэша для результата подстановки всех шорткодов в строке + /// + public class ShortcodesResult : IBaseCache + { + public required ShortcodesResultDto Data { get; set; } + + public DateTimeOffset Timestamp { get; set; } + + public required string Source { get; set; } + } + + public class ShortcodesResultDto + { + public required string Result { get; set; } + } +} diff --git a/PARR.TemplateMatcher/Services/Implemetaions/SimpleTemplateSynchronizer.cs b/PARR.TemplateMatcher/Services/Implemetaions/SimpleTemplateSynchronizer.cs index 0a34f0d8..bd59e2c0 100644 --- a/PARR.TemplateMatcher/Services/Implemetaions/SimpleTemplateSynchronizer.cs +++ b/PARR.TemplateMatcher/Services/Implemetaions/SimpleTemplateSynchronizer.cs @@ -476,7 +476,7 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer // Находим все шаблоны со статусом Unused var unusedTemplates = await templateService.Get() .Include(t => t.Unit) - .Where(t => t.StatusTypeId == TemplateStatusTypeEnum.Unused || t.StatusTypeId == TemplateStatusTypeEnum.Error) + .Where(t => t.StatusTypeId == TemplateStatusTypeEnum.Unused) .ToListAsync(); if (!unusedTemplates.Any())