mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-09 03:04:19 -04:00
Lots of Hangfire attempts to solve the lock issue. Not sure how to fix it. Added some APIs for streams.
This commit is contained in:
parent
bb0a59448f
commit
fad4ca4414
@ -128,9 +128,18 @@ namespace API.Controllers
|
||||
}
|
||||
|
||||
[HttpGet("recently-added")]
|
||||
public async Task<ActionResult<IEnumerable<SeriesDto>>> GetRecentlyAdded(int libraryId = 0)
|
||||
public async Task<ActionResult<IEnumerable<SeriesDto>>> GetRecentlyAdded(int libraryId = 0, int limit = 20)
|
||||
{
|
||||
return Ok(await _unitOfWork.SeriesRepository.GetRecentlyAdded(libraryId));
|
||||
return Ok(await _unitOfWork.SeriesRepository.GetRecentlyAdded(libraryId, limit));
|
||||
}
|
||||
|
||||
[HttpGet("in-progress")]
|
||||
public async Task<ActionResult<IEnumerable<SeriesDto>>> GetInProgress(int libraryId = 0, int limit = 20)
|
||||
{
|
||||
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername());
|
||||
return Ok(await _unitOfWork.SeriesRepository.GetInProgress(user.Id, libraryId, limit));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ using API.Interfaces;
|
||||
using AutoMapper;
|
||||
using AutoMapper.QueryableExtensions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace API.Data
|
||||
@ -282,20 +283,55 @@ namespace API.Data
|
||||
/// Returns a list of Series that were added within 2 weeks.
|
||||
/// </summary>
|
||||
/// <param name="libraryId">Library to restrict to, if 0, will apply to all libraries</param>
|
||||
/// <param name="limit"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<SeriesDto>> GetRecentlyAdded(int libraryId)
|
||||
public async Task<IEnumerable<SeriesDto>> GetRecentlyAdded(int libraryId, int limit)
|
||||
{
|
||||
// && (libraryId <= 0 || s.LibraryId == libraryId)
|
||||
// TODO: Remove 2 week condition
|
||||
var twoWeeksAgo = DateTime.Today.Subtract(TimeSpan.FromDays(14));
|
||||
_logger.LogDebug("2 weeks from today is: {Date}", twoWeeksAgo);
|
||||
return await _context.Series
|
||||
.Where(s => s.Created > twoWeeksAgo)
|
||||
.Take(20)
|
||||
.Where(s => s.Created > twoWeeksAgo && (libraryId <= 0 || s.LibraryId == libraryId))
|
||||
.Take(limit)
|
||||
.OrderBy(s => s.Created)
|
||||
.AsNoTracking()
|
||||
.ProjectTo<SeriesDto>(_mapper.ConfigurationProvider)
|
||||
.ToListAsync();
|
||||
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SeriesDto>> GetInProgress(int userId, int libraryId, int limit)
|
||||
{
|
||||
//&& (libraryId <= 0 || s.Series.LibraryId == libraryId)
|
||||
var twoWeeksAgo = DateTime.Today.Subtract(TimeSpan.FromDays(14));
|
||||
_logger.LogInformation("GetInProgress");
|
||||
_logger.LogDebug("2 weeks from today is: {Date}", twoWeeksAgo);
|
||||
// var series = await _context.Series
|
||||
// .Join(_context.AppUserProgresses, s => s.Id, progress => progress.SeriesId, (s, progress) => new
|
||||
// {
|
||||
// Series = s,
|
||||
// Progress = progress
|
||||
// })
|
||||
// .DefaultIfEmpty()
|
||||
// .Where(s => s.Series.Created > twoWeeksAgo
|
||||
// && s.Progress.AppUserId == userId
|
||||
// && s.Progress.PagesRead > s.Series.Pages)
|
||||
// .Take(limit)
|
||||
// .OrderBy(s => s.Series.Created)
|
||||
// .AsNoTracking()
|
||||
// .Select(s => s.Series)
|
||||
// .ProjectTo<SeriesDto>(_mapper.ConfigurationProvider)
|
||||
// .ToListAsync();
|
||||
var series = await _context.Series
|
||||
.Where(s => s.Created > twoWeeksAgo) // && (libraryId <= 0 || s.LibraryId == libraryId)
|
||||
.AsNoTracking()
|
||||
.ProjectTo<SeriesDto>(_mapper.ConfigurationProvider)
|
||||
.ToListAsync();
|
||||
|
||||
await AddSeriesModifiers(userId, series);
|
||||
|
||||
return series.Where(s => s.PagesRead > 0).Take(limit).ToList();
|
||||
}
|
||||
|
||||
|
||||
public async Task<IEnumerable<SeriesDto>> GetSeriesStream(int userId)
|
||||
|
@ -1,7 +1,12 @@
|
||||
namespace API.Extensions
|
||||
using API.Interfaces.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace API.Extensions
|
||||
{
|
||||
public class ServiceCollectionExtensions
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
|
||||
public static IServiceCollection AddStartupTask<T>(this IServiceCollection services)
|
||||
where T : class, IStartupTask
|
||||
=> services.AddTransient<IStartupTask, T>();
|
||||
}
|
||||
}
|
@ -55,6 +55,7 @@ namespace API.Interfaces
|
||||
|
||||
Task<byte[]> GetVolumeCoverImageAsync(int volumeId);
|
||||
Task<byte[]> GetSeriesCoverImageAsync(int seriesId);
|
||||
Task<IEnumerable<SeriesDto>> GetRecentlyAdded(int libraryId);
|
||||
Task<IEnumerable<SeriesDto>> GetInProgress(int userId, int libraryId, int limit);
|
||||
Task<IEnumerable<SeriesDto>> GetRecentlyAdded(int libraryId, int limit);
|
||||
}
|
||||
}
|
@ -25,6 +25,7 @@ namespace API.Middleware
|
||||
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
// BUG: I think Hangfire timeouts are triggering the middleware to hijack an API call
|
||||
try
|
||||
{
|
||||
await _next(context); // downstream middlewares or http call
|
||||
|
@ -3,6 +3,8 @@ using System.Threading.Tasks;
|
||||
using API.Data;
|
||||
using API.Entities;
|
||||
using API.Interfaces;
|
||||
using API.Interfaces.Services;
|
||||
using API.Services;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@ -40,6 +42,15 @@ namespace API
|
||||
var logger = services.GetRequiredService < ILogger<Program>>();
|
||||
logger.LogError(ex, "An error occurred during migration");
|
||||
}
|
||||
|
||||
// Load all tasks from DI (TODO: This is not working)
|
||||
var startupTasks = host.Services.GetServices<WarmupServicesStartupTask>();
|
||||
|
||||
// Execute all the tasks
|
||||
foreach (var startupTask in startupTasks)
|
||||
{
|
||||
await startupTask.ExecuteAsync();
|
||||
}
|
||||
|
||||
await host.RunAsync();
|
||||
}
|
||||
|
@ -21,11 +21,11 @@ namespace API.Services
|
||||
private readonly ICleanupService _cleanupService;
|
||||
private readonly IDirectoryService _directoryService;
|
||||
|
||||
public static BackgroundJobServer Client => new BackgroundJobServer();
|
||||
// new BackgroundJobServerOptions()
|
||||
// {
|
||||
// WorkerCount = 1
|
||||
// }
|
||||
public static BackgroundJobServer Client => new BackgroundJobServer(new BackgroundJobServerOptions()
|
||||
{
|
||||
WorkerCount = 1
|
||||
});
|
||||
|
||||
|
||||
public TaskScheduler(ICacheService cacheService, ILogger<TaskScheduler> logger, IScannerService scannerService,
|
||||
IUnitOfWork unitOfWork, IMetadataService metadataService, IBackupService backupService, ICleanupService cleanupService,
|
||||
|
@ -33,7 +33,7 @@ namespace API.Services.Tasks
|
||||
_metadataService = metadataService;
|
||||
}
|
||||
|
||||
[DisableConcurrentExecution(timeoutInSeconds: 5)]
|
||||
//[DisableConcurrentExecution(timeoutInSeconds: 5)]
|
||||
[AutomaticRetry(Attempts = 0, LogEvents = false, OnAttemptsExceeded = AttemptsExceededAction.Delete)]
|
||||
public void ScanLibraries()
|
||||
{
|
||||
@ -64,7 +64,7 @@ namespace API.Services.Tasks
|
||||
_scannedSeries = null;
|
||||
}
|
||||
|
||||
[DisableConcurrentExecution(5)]
|
||||
//[DisableConcurrentExecution(5)]
|
||||
[AutomaticRetry(Attempts = 0, LogEvents = false, OnAttemptsExceeded = AttemptsExceededAction.Delete)]
|
||||
public void ScanLibrary(int libraryId, bool forceUpdate)
|
||||
{
|
||||
|
@ -18,14 +18,13 @@ namespace API.Services
|
||||
_provider = provider;
|
||||
}
|
||||
|
||||
public Task ExecuteAsync(CancellationToken cancellationToken)
|
||||
public Task ExecuteAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
using (var scope = _provider.CreateScope())
|
||||
using var scope = _provider.CreateScope();
|
||||
foreach (var singleton in GetServices(_services))
|
||||
{
|
||||
foreach (var singleton in GetServices(_services))
|
||||
{
|
||||
scope.ServiceProvider.GetServices(singleton);
|
||||
}
|
||||
Console.WriteLine("DI preloading of " + singleton.FullName);
|
||||
scope.ServiceProvider.GetServices(singleton);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
|
@ -64,10 +64,9 @@ namespace API
|
||||
services.AddResponseCaching();
|
||||
|
||||
|
||||
services
|
||||
.AddStartupTask<WarmupServicesStartupTask>()
|
||||
.TryAddSingleton(services);
|
||||
|
||||
// services
|
||||
// .AddStartupTask<WarmupServicesStartupTask>()
|
||||
// //.TryAddSingleton(services);
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
@ -134,7 +133,7 @@ namespace API
|
||||
{
|
||||
Console.WriteLine("Server is shutting down. Going to dispose Hangfire");
|
||||
//this code is called when the application stops
|
||||
//TaskScheduler.Client.Dispose();
|
||||
TaskScheduler.Client.Dispose();
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user