Cleanup from the Release (#2127)
* Added an FAQ link on the Kavita+ tab. * Don't query Kavita+ for ratings on comic libraries as there is no upstream provider yet. * Jumpbar keys are a little hard to click * Fixed an issue where libraries that don't allow scrobbling could be scrobbled when generating past history with read events. * Made the min/max release year on metadata filter number and removed the spin arrows for styling. * Fixed disable tabs color contrast due to bootstrap undocumented change. * Refactored whole codebase to unify caching mechanism. Upped the default cache memory amount to 75 to account for the extra data load. Still LRU. Fixed an issue where Cache key was using Port instead. Refactored all the Configuration code to use strongly typed deserialization. * Fixed an issue where get latest progress would throw an exception if there was no progress due to LINQ and MAX query. * Fixed a bug where Send to Device wasn't present on Series cards. * Hooked up the ability to change the cache size for Kavita via the UI.
This commit is contained in:
parent
1ed8889d08
commit
81da9dc444
37 changed files with 402 additions and 272 deletions
|
@ -88,7 +88,8 @@ public class DeviceController : BaseApiController
|
|||
return BadRequest("Send to device cannot be used with Kavita's email service. Please configure your own.");
|
||||
|
||||
var userId = await _unitOfWork.UserRepository.GetUserIdByUsernameAsync(User.GetUsername());
|
||||
await _eventHub.SendMessageToAsync(MessageFactory.NotificationProgress, MessageFactory.SendingToDeviceEvent($"Transferring files to your device", "started"), userId);
|
||||
await _eventHub.SendMessageToAsync(MessageFactory.NotificationProgress,
|
||||
MessageFactory.SendingToDeviceEvent($"Transferring files to your device", "started"), userId);
|
||||
try
|
||||
{
|
||||
var success = await _deviceService.SendTo(dto.ChapterIds, dto.DeviceId);
|
||||
|
@ -100,7 +101,8 @@ public class DeviceController : BaseApiController
|
|||
}
|
||||
finally
|
||||
{
|
||||
await _eventHub.SendMessageToAsync(MessageFactory.SendingToDevice, MessageFactory.SendingToDeviceEvent($"Transferring files to your device", "ended"), userId);
|
||||
await _eventHub.SendMessageToAsync(MessageFactory.SendingToDevice,
|
||||
MessageFactory.SendingToDeviceEvent($"Transferring files to your device", "ended"), userId);
|
||||
}
|
||||
|
||||
return BadRequest("There was an error sending the file to the device");
|
||||
|
@ -108,6 +110,42 @@ public class DeviceController : BaseApiController
|
|||
|
||||
|
||||
|
||||
[HttpPost("send-series-to")]
|
||||
public async Task<ActionResult> SendSeriesToDevice(SendSeriesToDeviceDto dto)
|
||||
{
|
||||
if (dto.SeriesId <= 0) return BadRequest("SeriesId must be greater than 0");
|
||||
if (dto.DeviceId < 0) return BadRequest("DeviceId must be greater than 0");
|
||||
|
||||
if (await _emailService.IsDefaultEmailService())
|
||||
return BadRequest("Send to device cannot be used with Kavita's email service. Please configure your own.");
|
||||
|
||||
var userId = await _unitOfWork.UserRepository.GetUserIdByUsernameAsync(User.GetUsername());
|
||||
await _eventHub.SendMessageToAsync(MessageFactory.NotificationProgress, MessageFactory.SendingToDeviceEvent($"Transferring files to your device", "started"), userId);
|
||||
|
||||
var series =
|
||||
await _unitOfWork.SeriesRepository.GetSeriesByIdAsync(dto.SeriesId,
|
||||
SeriesIncludes.Volumes | SeriesIncludes.Chapters);
|
||||
if (series == null) return BadRequest("Series doesn't Exist");
|
||||
var chapterIds = series.Volumes.SelectMany(v => v.Chapters.Select(c => c.Id)).ToList();
|
||||
try
|
||||
{
|
||||
var success = await _deviceService.SendTo(chapterIds, dto.DeviceId);
|
||||
if (success) return Ok();
|
||||
}
|
||||
catch (KavitaException ex)
|
||||
{
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await _eventHub.SendMessageToAsync(MessageFactory.SendingToDevice, MessageFactory.SendingToDeviceEvent($"Transferring files to your device", "ended"), userId);
|
||||
}
|
||||
|
||||
return BadRequest("There was an error sending the file(s) to the device");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using API.Constants;
|
||||
using API.Data;
|
||||
using API.Data.Repositories;
|
||||
using API.DTOs;
|
||||
|
@ -18,11 +18,10 @@ using API.Services;
|
|||
using API.Services.Tasks.Scanner;
|
||||
using API.SignalR;
|
||||
using AutoMapper;
|
||||
using EasyCaching.Core;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using TaskScheduler = API.Services.TaskScheduler;
|
||||
|
||||
namespace API.Controllers;
|
||||
|
@ -37,12 +36,13 @@ public class LibraryController : BaseApiController
|
|||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly IEventHub _eventHub;
|
||||
private readonly ILibraryWatcher _libraryWatcher;
|
||||
private readonly IMemoryCache _memoryCache;
|
||||
private readonly IEasyCachingProvider _libraryCacheProvider;
|
||||
private const string CacheKey = "library_";
|
||||
|
||||
public LibraryController(IDirectoryService directoryService,
|
||||
ILogger<LibraryController> logger, IMapper mapper, ITaskScheduler taskScheduler,
|
||||
IUnitOfWork unitOfWork, IEventHub eventHub, ILibraryWatcher libraryWatcher, IMemoryCache memoryCache)
|
||||
IUnitOfWork unitOfWork, IEventHub eventHub, ILibraryWatcher libraryWatcher,
|
||||
IEasyCachingProviderFactory cachingProviderFactory)
|
||||
{
|
||||
_directoryService = directoryService;
|
||||
_logger = logger;
|
||||
|
@ -51,7 +51,8 @@ public class LibraryController : BaseApiController
|
|||
_unitOfWork = unitOfWork;
|
||||
_eventHub = eventHub;
|
||||
_libraryWatcher = libraryWatcher;
|
||||
_memoryCache = memoryCache;
|
||||
|
||||
_libraryCacheProvider = cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.Library);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -102,7 +103,7 @@ public class LibraryController : BaseApiController
|
|||
_taskScheduler.ScanLibrary(library.Id);
|
||||
await _eventHub.SendMessageAsync(MessageFactory.LibraryModified,
|
||||
MessageFactory.LibraryModifiedEvent(library.Id, "create"), false);
|
||||
_memoryCache.RemoveByPrefix(CacheKey);
|
||||
await _libraryCacheProvider.RemoveByPrefixAsync(CacheKey);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
@ -134,23 +135,19 @@ public class LibraryController : BaseApiController
|
|||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public ActionResult<IEnumerable<LibraryDto>> GetLibraries()
|
||||
public async Task<ActionResult<IEnumerable<LibraryDto>>> GetLibraries()
|
||||
{
|
||||
var username = User.GetUsername();
|
||||
if (string.IsNullOrEmpty(username)) return Unauthorized();
|
||||
|
||||
var cacheKey = CacheKey + username;
|
||||
if (_memoryCache.TryGetValue(cacheKey, out string cachedValue))
|
||||
{
|
||||
return Ok(JsonConvert.DeserializeObject<IEnumerable<LibraryDto>>(cachedValue));
|
||||
}
|
||||
var result = await _libraryCacheProvider.GetAsync<IEnumerable<LibraryDto>>(cacheKey);
|
||||
if (result.HasValue) return Ok(result.Value);
|
||||
|
||||
var ret = _unitOfWork.LibraryRepository.GetLibraryDtosForUsernameAsync(username);
|
||||
var cacheEntryOptions = new MemoryCacheEntryOptions()
|
||||
.SetSize(1)
|
||||
.SetAbsoluteExpiration(TimeSpan.FromHours(24));
|
||||
_memoryCache.Set(cacheKey, JsonConvert.SerializeObject(ret), cacheEntryOptions);
|
||||
await _libraryCacheProvider.SetAsync(CacheKey, ret, TimeSpan.FromHours(24));
|
||||
_logger.LogDebug("Caching libraries for {Key}", cacheKey);
|
||||
|
||||
return Ok(ret);
|
||||
}
|
||||
|
||||
|
@ -211,7 +208,7 @@ public class LibraryController : BaseApiController
|
|||
{
|
||||
_logger.LogInformation("Added: {SelectedLibraries} to {Username}",libraryString, updateLibraryForUserDto.Username);
|
||||
// Bust cache
|
||||
_memoryCache.RemoveByPrefix(CacheKey);
|
||||
await _libraryCacheProvider.RemoveByPrefixAsync(CacheKey);
|
||||
return Ok(_mapper.Map<MemberDto>(user));
|
||||
}
|
||||
|
||||
|
@ -334,7 +331,7 @@ public class LibraryController : BaseApiController
|
|||
|
||||
await _unitOfWork.CommitAsync();
|
||||
|
||||
_memoryCache.RemoveByPrefix(CacheKey);
|
||||
await _libraryCacheProvider.RemoveByPrefixAsync(CacheKey);
|
||||
|
||||
if (chapterIds.Any())
|
||||
{
|
||||
|
@ -433,7 +430,7 @@ public class LibraryController : BaseApiController
|
|||
await _eventHub.SendMessageAsync(MessageFactory.LibraryModified,
|
||||
MessageFactory.LibraryModifiedEvent(library.Id, "update"), false);
|
||||
|
||||
_memoryCache.RemoveByPrefix(CacheKey);
|
||||
await _libraryCacheProvider.RemoveByPrefixAsync(CacheKey);
|
||||
|
||||
return Ok();
|
||||
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using API.Constants;
|
||||
using API.DTOs;
|
||||
using API.DTOs.SeriesDetail;
|
||||
using API.Services.Plus;
|
||||
using EasyCaching.Core;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace API.Controllers;
|
||||
|
||||
|
@ -20,16 +17,18 @@ public class RatingController : BaseApiController
|
|||
{
|
||||
private readonly ILicenseService _licenseService;
|
||||
private readonly IRatingService _ratingService;
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly ILogger<RatingController> _logger;
|
||||
public const string CacheKey = "rating-";
|
||||
private readonly IEasyCachingProvider _cacheProvider;
|
||||
public const string CacheKey = "rating_";
|
||||
|
||||
public RatingController(ILicenseService licenseService, IRatingService ratingService, IMemoryCache memoryCache, ILogger<RatingController> logger)
|
||||
public RatingController(ILicenseService licenseService, IRatingService ratingService,
|
||||
ILogger<RatingController> logger, IEasyCachingProviderFactory cachingProviderFactory)
|
||||
{
|
||||
_licenseService = licenseService;
|
||||
_ratingService = ratingService;
|
||||
_cache = memoryCache;
|
||||
_logger = logger;
|
||||
|
||||
_cacheProvider = cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRatings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -47,27 +46,16 @@ public class RatingController : BaseApiController
|
|||
}
|
||||
|
||||
var cacheKey = CacheKey + seriesId;
|
||||
var setCache = false;
|
||||
IEnumerable<RatingDto> ratings;
|
||||
if (_cache.TryGetValue(cacheKey, out string cachedData))
|
||||
var results = await _cacheProvider.GetAsync<IEnumerable<RatingDto>>(cacheKey);
|
||||
if (results.HasValue)
|
||||
{
|
||||
ratings = JsonConvert.DeserializeObject<IEnumerable<RatingDto>>(cachedData);
|
||||
}
|
||||
else
|
||||
{
|
||||
ratings = await _ratingService.GetRatings(seriesId);
|
||||
setCache = true;
|
||||
}
|
||||
|
||||
if (setCache)
|
||||
{
|
||||
var cacheEntryOptions = new MemoryCacheEntryOptions()
|
||||
.SetSize(1)
|
||||
.SetAbsoluteExpiration(TimeSpan.FromHours(24));
|
||||
_cache.Set(cacheKey, JsonConvert.SerializeObject(ratings), cacheEntryOptions);
|
||||
_logger.LogDebug("Caching external rating for {Key}", cacheKey);
|
||||
return Ok(results.Value);
|
||||
}
|
||||
|
||||
var ratings = await _ratingService.GetRatings(seriesId);
|
||||
await _cacheProvider.SetAsync(cacheKey, ratings, TimeSpan.FromHours(24));
|
||||
_logger.LogDebug("Caching external rating for {Key}", cacheKey);
|
||||
return Ok(ratings);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ using API.DTOs.Recommendation;
|
|||
using API.Extensions;
|
||||
using API.Helpers;
|
||||
using API.Services.Plus;
|
||||
using EasyCaching.Core;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Newtonsoft.Json;
|
||||
|
@ -20,16 +21,16 @@ public class RecommendedController : BaseApiController
|
|||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly IRecommendationService _recommendationService;
|
||||
private readonly ILicenseService _licenseService;
|
||||
private readonly IMemoryCache _cache;
|
||||
public const string CacheKey = "recommendation-";
|
||||
private readonly IEasyCachingProvider _cacheProvider;
|
||||
public const string CacheKey = "recommendation_";
|
||||
|
||||
public RecommendedController(IUnitOfWork unitOfWork, IRecommendationService recommendationService,
|
||||
ILicenseService licenseService, IMemoryCache cache)
|
||||
ILicenseService licenseService, IEasyCachingProviderFactory cachingProviderFactory)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_recommendationService = recommendationService;
|
||||
_licenseService = licenseService;
|
||||
_cache = cache;
|
||||
_cacheProvider = cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRecommendations);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -53,16 +54,14 @@ public class RecommendedController : BaseApiController
|
|||
}
|
||||
|
||||
var cacheKey = $"{CacheKey}-{seriesId}-{userId}";
|
||||
if (_cache.TryGetValue(cacheKey, out string cachedData))
|
||||
var results = await _cacheProvider.GetAsync<RecommendationDto>(cacheKey);
|
||||
if (results.HasValue)
|
||||
{
|
||||
return Ok(JsonConvert.DeserializeObject<RecommendationDto>(cachedData));
|
||||
return Ok(results.Value);
|
||||
}
|
||||
|
||||
var ret = await _recommendationService.GetRecommendationsForSeries(userId, seriesId);
|
||||
var cacheEntryOptions = new MemoryCacheEntryOptions()
|
||||
.SetSize(ret.OwnedSeries.Count() + ret.ExternalSeries.Count())
|
||||
.SetAbsoluteExpiration(TimeSpan.FromHours(10));
|
||||
_cache.Set(cacheKey, JsonConvert.SerializeObject(ret), cacheEntryOptions);
|
||||
await _cacheProvider.SetAsync(cacheKey, ret, TimeSpan.FromHours(10));
|
||||
return Ok(ret);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ using API.Helpers.Builders;
|
|||
using API.Services;
|
||||
using API.Services.Plus;
|
||||
using AutoMapper;
|
||||
using EasyCaching.Core;
|
||||
using Hangfire;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
@ -26,20 +27,22 @@ public class ReviewController : BaseApiController
|
|||
private readonly ILicenseService _licenseService;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly IReviewService _reviewService;
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly IScrobblingService _scrobblingService;
|
||||
public const string CacheKey = "review-";
|
||||
private readonly IEasyCachingProvider _cacheProvider;
|
||||
public const string CacheKey = "review_";
|
||||
|
||||
public ReviewController(ILogger<ReviewController> logger, IUnitOfWork unitOfWork, ILicenseService licenseService,
|
||||
IMapper mapper, IReviewService reviewService, IMemoryCache cache, IScrobblingService scrobblingService)
|
||||
IMapper mapper, IReviewService reviewService, IScrobblingService scrobblingService,
|
||||
IEasyCachingProviderFactory cachingProviderFactory)
|
||||
{
|
||||
_logger = logger;
|
||||
_unitOfWork = unitOfWork;
|
||||
_licenseService = licenseService;
|
||||
_mapper = mapper;
|
||||
_reviewService = reviewService;
|
||||
_cache = cache;
|
||||
_scrobblingService = scrobblingService;
|
||||
|
||||
_cacheProvider = cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusReviews);
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,15 +66,26 @@ public class ReviewController : BaseApiController
|
|||
var cacheKey = CacheKey + seriesId;
|
||||
IEnumerable<UserReviewDto> externalReviews;
|
||||
var setCache = false;
|
||||
if (_cache.TryGetValue(cacheKey, out string cachedData))
|
||||
|
||||
var result = await _cacheProvider.GetAsync<IEnumerable<UserReviewDto>>(cacheKey);
|
||||
if (result.HasValue)
|
||||
{
|
||||
externalReviews = JsonConvert.DeserializeObject<IEnumerable<UserReviewDto>>(cachedData);
|
||||
externalReviews = result.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
externalReviews = await _reviewService.GetReviewsForSeries(userId, seriesId);
|
||||
setCache = true;
|
||||
}
|
||||
// if (_cache.TryGetValue(cacheKey, out string cachedData))
|
||||
// {
|
||||
// externalReviews = JsonConvert.DeserializeObject<IEnumerable<UserReviewDto>>(cachedData);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// externalReviews = await _reviewService.GetReviewsForSeries(userId, seriesId);
|
||||
// setCache = true;
|
||||
// }
|
||||
|
||||
// Fetch external reviews and splice them in
|
||||
foreach (var r in externalReviews)
|
||||
|
@ -81,10 +95,11 @@ public class ReviewController : BaseApiController
|
|||
|
||||
if (setCache)
|
||||
{
|
||||
var cacheEntryOptions = new MemoryCacheEntryOptions()
|
||||
.SetSize(userRatings.Count)
|
||||
.SetAbsoluteExpiration(TimeSpan.FromHours(10));
|
||||
_cache.Set(cacheKey, JsonConvert.SerializeObject(externalReviews), cacheEntryOptions);
|
||||
// var cacheEntryOptions = new MemoryCacheEntryOptions()
|
||||
// .SetSize(userRatings.Count)
|
||||
// .SetAbsoluteExpiration(TimeSpan.FromHours(10));
|
||||
//_cache.Set(cacheKey, JsonConvert.SerializeObject(externalReviews), cacheEntryOptions);
|
||||
await _cacheProvider.SetAsync(cacheKey, externalReviews, TimeSpan.FromHours(10));
|
||||
_logger.LogDebug("Caching external reviews for {Key}", cacheKey);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using API.Constants;
|
||||
|
@ -15,12 +14,11 @@ using API.Extensions;
|
|||
using API.Helpers;
|
||||
using API.Services;
|
||||
using API.Services.Plus;
|
||||
using Kavita.Common;
|
||||
using EasyCaching.Core;
|
||||
using Kavita.Common.Extensions;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace API.Controllers;
|
||||
|
@ -31,19 +29,25 @@ public class SeriesController : BaseApiController
|
|||
private readonly ITaskScheduler _taskScheduler;
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly ISeriesService _seriesService;
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly ILicenseService _licenseService;
|
||||
private readonly IEasyCachingProvider _ratingCacheProvider;
|
||||
private readonly IEasyCachingProvider _reviewCacheProvider;
|
||||
private readonly IEasyCachingProvider _recommendationCacheProvider;
|
||||
|
||||
|
||||
public SeriesController(ILogger<SeriesController> logger, ITaskScheduler taskScheduler, IUnitOfWork unitOfWork,
|
||||
ISeriesService seriesService, IMemoryCache cache, ILicenseService licenseService)
|
||||
ISeriesService seriesService, ILicenseService licenseService,
|
||||
IEasyCachingProviderFactory cachingProviderFactory)
|
||||
{
|
||||
_logger = logger;
|
||||
_taskScheduler = taskScheduler;
|
||||
_unitOfWork = unitOfWork;
|
||||
_seriesService = seriesService;
|
||||
_cache = cache;
|
||||
_licenseService = licenseService;
|
||||
|
||||
_ratingCacheProvider = cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRatings);
|
||||
_reviewCacheProvider = cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusReviews);
|
||||
_recommendationCacheProvider = cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRecommendations);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
|
@ -344,12 +348,13 @@ public class SeriesController : BaseApiController
|
|||
if (await _licenseService.HasActiveLicense())
|
||||
{
|
||||
_logger.LogDebug("Clearing cache as series weblinks may have changed");
|
||||
_cache.Remove(ReviewController.CacheKey + updateSeriesMetadataDto.SeriesMetadata.SeriesId);
|
||||
_cache.Remove(RatingController.CacheKey + updateSeriesMetadataDto.SeriesMetadata.SeriesId);
|
||||
await _reviewCacheProvider.RemoveAsync(ReviewController.CacheKey + updateSeriesMetadataDto.SeriesMetadata.SeriesId);
|
||||
await _ratingCacheProvider.RemoveAsync(RatingController.CacheKey + updateSeriesMetadataDto.SeriesMetadata.SeriesId);
|
||||
|
||||
var allUsers = (await _unitOfWork.UserRepository.GetAllUsersAsync()).Select(s => s.Id);
|
||||
foreach (var userId in allUsers)
|
||||
{
|
||||
_cache.Remove(RecommendedController.CacheKey + $"{updateSeriesMetadataDto.SeriesMetadata.SeriesId}-{userId}");
|
||||
await _recommendationCacheProvider.RemoveAsync(RecommendedController.CacheKey + $"{updateSeriesMetadataDto.SeriesMetadata.SeriesId}-{userId}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using API.Constants;
|
||||
using API.Data;
|
||||
using API.DTOs.Jobs;
|
||||
using API.DTOs.MediaErrors;
|
||||
|
@ -13,6 +14,7 @@ using API.Extensions;
|
|||
using API.Helpers;
|
||||
using API.Services;
|
||||
using API.Services.Tasks;
|
||||
using EasyCaching.Core;
|
||||
using Hangfire;
|
||||
using Hangfire.Storage;
|
||||
using Kavita.Common;
|
||||
|
@ -38,12 +40,12 @@ public class ServerController : BaseApiController
|
|||
private readonly IAccountService _accountService;
|
||||
private readonly ITaskScheduler _taskScheduler;
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly IMemoryCache _memoryCache;
|
||||
private readonly IEasyCachingProviderFactory _cachingProviderFactory;
|
||||
|
||||
public ServerController(ILogger<ServerController> logger,
|
||||
IBackupService backupService, IArchiveService archiveService, IVersionUpdaterService versionUpdaterService, IStatsService statsService,
|
||||
ICleanupService cleanupService, IScannerService scannerService, IAccountService accountService,
|
||||
ITaskScheduler taskScheduler, IUnitOfWork unitOfWork, IMemoryCache memoryCache)
|
||||
ITaskScheduler taskScheduler, IUnitOfWork unitOfWork, IEasyCachingProviderFactory cachingProviderFactory)
|
||||
{
|
||||
_logger = logger;
|
||||
_backupService = backupService;
|
||||
|
@ -55,7 +57,7 @@ public class ServerController : BaseApiController
|
|||
_accountService = accountService;
|
||||
_taskScheduler = taskScheduler;
|
||||
_unitOfWork = unitOfWork;
|
||||
_memoryCache = memoryCache;
|
||||
_cachingProviderFactory = cachingProviderFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -244,10 +246,16 @@ public class ServerController : BaseApiController
|
|||
/// <returns></returns>
|
||||
[Authorize("RequireAdminRole")]
|
||||
[HttpPost("bust-review-and-rec-cache")]
|
||||
public ActionResult BustReviewAndRecCache()
|
||||
public async Task<ActionResult> BustReviewAndRecCache()
|
||||
{
|
||||
_memoryCache.Clear();
|
||||
return Ok();
|
||||
_logger.LogInformation("Busting Kavita+ Cache");
|
||||
var provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusReviews);
|
||||
await provider.FlushAsync();
|
||||
provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRecommendations);
|
||||
await provider.FlushAsync();
|
||||
provider = _cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.KavitaPlusRatings);
|
||||
await provider.FlushAsync();
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -191,6 +191,14 @@ public class SettingsController : BaseApiController
|
|||
_unitOfWork.SettingsRepository.Update(setting);
|
||||
}
|
||||
|
||||
if (setting.Key == ServerSettingKey.CacheSize && updateSettingsDto.CacheSize + string.Empty != setting.Value)
|
||||
{
|
||||
setting.Value = updateSettingsDto.CacheSize + string.Empty;
|
||||
// CacheSize is managed in appSetting.json
|
||||
Configuration.CacheSize = updateSettingsDto.CacheSize;
|
||||
_unitOfWork.SettingsRepository.Update(setting);
|
||||
}
|
||||
|
||||
if (setting.Key == ServerSettingKey.IpAddresses && updateSettingsDto.IpAddresses != setting.Value)
|
||||
{
|
||||
if (OsInfo.IsDocker) continue;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue