Simplify infrastructure services and move all recurring jobs to Hangfire
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
using Mediator;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Musify.Application.Configuration;
|
||||
using Musify.Application.Contracts;
|
||||
|
||||
namespace Musify.Application.UploadIntents;
|
||||
|
||||
/// <summary>Deletes temporary upload objects that nobody claimed within the retention window.</summary>
|
||||
public record DeleteStaleTempUploadsCommand : ICommand<int>;
|
||||
|
||||
public class DeleteStaleTempUploadsCommandHandler(
|
||||
IStorageService storageService,
|
||||
ApplicationStorageConfiguration storageConfiguration,
|
||||
UploadIntentConfiguration uploadIntentConfiguration,
|
||||
ILogger<DeleteStaleTempUploadsCommandHandler> logger)
|
||||
: ICommandHandler<DeleteStaleTempUploadsCommand, int>
|
||||
{
|
||||
public async ValueTask<int> Handle(DeleteStaleTempUploadsCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var cutOff = DateTime.UtcNow.AddDays(-uploadIntentConfiguration.TempUploadsRetentionDays);
|
||||
var deleted = 0;
|
||||
|
||||
await foreach (var (key, lastModified) in storageService.ListObjectsAsync(
|
||||
storageConfiguration.Bucket, uploadIntentConfiguration.TempRootPrefix, cancellationToken))
|
||||
{
|
||||
if (lastModified >= cutOff)
|
||||
continue;
|
||||
|
||||
await storageService.RemoveFileAsync(storageConfiguration.Bucket, key, cancellationToken);
|
||||
deleted++;
|
||||
}
|
||||
|
||||
if (deleted > 0)
|
||||
logger.LogInformation("Deleted {Deleted} orphaned temp uploads", deleted);
|
||||
|
||||
return deleted;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using Mediator;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Musify.Application.Configuration;
|
||||
using Musify.Application.Contracts;
|
||||
using Musify.Domain.ValueObjects;
|
||||
|
||||
namespace Musify.Application.UploadIntents;
|
||||
|
||||
/// <summary>Marks overdue upload intents as expired and deletes the ones expired for longer than the retention window.</summary>
|
||||
public record ExpireUploadIntentsCommand : ICommand<int>;
|
||||
|
||||
public class ExpireUploadIntentsCommandHandler(
|
||||
IDatabase database,
|
||||
UploadIntentConfiguration uploadIntentConfiguration,
|
||||
ILogger<ExpireUploadIntentsCommandHandler> logger)
|
||||
: ICommandHandler<ExpireUploadIntentsCommand, int>
|
||||
{
|
||||
public async ValueTask<int> Handle(ExpireUploadIntentsCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
var expiredIntents = await database.UploadIntents
|
||||
.Where(intent => intent.Status == UploadIntentStatus.Issued && intent.ExpiresAt < now)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
foreach (var intent in expiredIntents)
|
||||
intent.Status = UploadIntentStatus.Expired;
|
||||
|
||||
var retentionCutoff = now.AddDays(-uploadIntentConfiguration.ExpiredIntentsRetentionDays);
|
||||
var oldExpiredIntents = await database.UploadIntents
|
||||
.Where(intent => intent.Status == UploadIntentStatus.Expired && intent.ExpiresAt < retentionCutoff)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
database.UploadIntents.RemoveRange(oldExpiredIntents);
|
||||
|
||||
if (expiredIntents.Count == 0 && oldExpiredIntents.Count == 0)
|
||||
return 0;
|
||||
|
||||
await database.SaveChangesAsync(cancellationToken);
|
||||
logger.LogInformation("Marked {Expired} upload intents as expired and deleted {Deleted} old ones",
|
||||
expiredIntents.Count, oldExpiredIntents.Count);
|
||||
|
||||
return expiredIntents.Count + oldExpiredIntents.Count;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user