Files
parr_api/PARR.Core/Services/HelpDocument/Implementations/HelpDocumentService.cs

105 lines
5.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Microsoft.Extensions.Logging;
using PARR.Core.Common.Interfaces;
using PARR.Core.Services.HelpDocument.Interfaces;
using PARR.Domain.Cache;
using PARR.Domain.DTOs.HelpDocument;
using PARR.Domain.Settings;
namespace PARR.Core.Services.HelpDocument.Implementations
{
internal class HelpDocumentService : IHelpDocumentService
{
private readonly IHelpDocumentProvider _helpProvider;
private readonly IRedisCacheService _redisCacheService;
private readonly HelpDocumentSettings _helpDocumentSettings;
private readonly ILogger<HelpDocumentService> _logger;
public HelpDocumentService(
IHelpDocumentProvider helpProvider,
IRedisCacheService redisCacheService,
HelpDocumentSettings helpDocumentSettings,
ILogger<HelpDocumentService> logger
)
{
_helpProvider = helpProvider;
_redisCacheService = redisCacheService;
_helpDocumentSettings = helpDocumentSettings;
_logger = logger;
}
public async Task<HelpDocumentResult?> GetHelpDocumentAsync(string helpId)
{
if (string.IsNullOrEmpty(helpId))
{
_logger.LogWarning("Значение helpId: '{helpId}' пустое.", helpId);
return null;
}
var cacheKey = _redisCacheService.GetKey(CacheKeys.HelpDocument.HelpDocumentItem(helpId));
_logger.LogDebug("Запрос справки. Проверка наличия в Redis по ключу: {CacheKey}", cacheKey);
// 1. Попытка получить данные из Redis
var cachedData = await _redisCacheService.GetCachedDataAsync<HelpDocumentResult?>(cacheKey, useCompression: true);
if (cachedData != null)
{
_logger.LogInformation("Документ справки успешно извлечен из кэша Redis. HelpId: {HelpId}", helpId);
return cachedData;
}
_logger.LogDebug("Кэш пуст или недоступен. Запрос документа напрямую через провайдер для HelpId: {HelpId}", helpId);
// 2. Если в Redis пусто, идем в GitLab через наш провайдер
var remoteDocument = await _helpProvider.GetDocumentAsync(helpId);
if (remoteDocument == null)
{
_logger.LogWarning("Документ не найден ни в Redis, ни в GitLab. HelpId: {HelpId}", helpId);
// Создаем понятный для пользователя текст-заглушку если нет документации
remoteDocument = new HelpDocumentResult
{
HelpId = helpId,
Title = "Раздел в разработке",
Content = "### 📚 Отсутствует документация по данному разделу.\n\n" +
"Если у вас возникли срочные вопросы, свяжитесь с теми, кто знает на них ответы :)."
};
// Кэшируем заглушку на короткий срок (например, на 5-10 минут), а не на 24 часа.
// Это нужно, чтобы как только аналитик создаст файл и прилетит хук, кэш обновился,
// но при этом частые клики пользователей по сломанному вопросику не спамили GitLab запросами 404.
await _redisCacheService.SetCachedDataAsync(cacheKey, remoteDocument, _helpDocumentSettings.ShortTTL, useCompression: true);
return remoteDocument;
}
// 3. Сохраняем полученный документ в Redis для последующих запросов
await _redisCacheService.SetCachedDataAsync(cacheKey, remoteDocument, _helpDocumentSettings.CacheTTL, useCompression: true);
_logger.LogDebug("Вернул документацию из провайдера для HelpId: {HelpId}", helpId);
return remoteDocument;
}
public async Task ClearCacheAsync(string helpId)
{
if (string.IsNullOrEmpty(helpId))
{
_logger.LogWarning("Попытка очистки кэша: передан пустой helpId.");
return;
}
var cacheKey = _redisCacheService.GetKey(CacheKeys.HelpDocument.HelpDocumentItem(helpId));
_logger.LogInformation("Удаление документа справки из кэша Redis по вебхуку. Ключ: {CacheKey}", cacheKey);
await _redisCacheService.DeleteCachedDataAsync(cacheKey);
}
}
}