feat: replace Hangfire with Coravel

This commit is contained in:
sam 2024-09-03 16:29:51 +02:00
parent ef221b2c45
commit 0aadc5fb47
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
19 changed files with 305 additions and 309 deletions

View file

@ -0,0 +1,51 @@
using Foxnouns.Backend.Database;
using Foxnouns.Backend.Jobs;
using Foxnouns.Backend.Services;
using Foxnouns.Backend.Utils;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Webp;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Transforms;
namespace Foxnouns.Backend.Extensions;
public static class AvatarObjectExtensions
{
private static readonly string[] ValidContentTypes = ["image/png", "image/webp", "image/jpeg"];
public static async Task
DeleteMemberAvatarAsync(this ObjectStorageService objectStorage, Snowflake id, string hash) =>
await objectStorage.RemoveObjectAsync(MemberAvatarUpdateInvocable.Path(id, hash));
public static async Task
DeleteUserAvatarAsync(this ObjectStorageService objectStorage, Snowflake id, string hash) =>
await objectStorage.RemoveObjectAsync(UserAvatarUpdateInvocable.Path(id, hash));
public static async Task<Stream> ConvertBase64UriToAvatar(this string uri)
{
if (!uri.StartsWith("data:image/"))
throw new ArgumentException("Not a data URI", nameof(uri));
var split = uri.Remove(0, "data:".Length).Split(";base64,");
var contentType = split[0];
var encoded = split[1];
if (!ValidContentTypes.Contains(contentType))
throw new ArgumentException("Invalid content type for image", nameof(uri));
if (!AuthUtils.TryFromBase64String(encoded, out var rawImage))
throw new ArgumentException("Invalid base64 string", nameof(uri));
var image = Image.Load(rawImage);
var processor = new ResizeProcessor(
new ResizeOptions { Size = new Size(512), Mode = ResizeMode.Crop, Position = AnchorPositionMode.Center },
image.Size
);
image.Mutate(x => x.ApplyProcessor(processor));
var stream = new MemoryStream(64 * 1024);
await image.SaveAsync(stream, new WebpEncoder { Quality = 95, NearLossless = false });
return stream;
}
}

View file

@ -1,6 +1,8 @@
using App.Metrics;
using App.Metrics.AspNetCore;
using App.Metrics.Formatters.Prometheus;
using Coravel;
using Coravel.Queuing.Interfaces;
using Foxnouns.Backend.Database;
using Foxnouns.Backend.Jobs;
using Foxnouns.Backend.Middleware;
@ -93,6 +95,7 @@ public static class WebApplicationExtensions
return builder
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appSettings.json", true)
.AddIniFile(file, optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
}
@ -105,8 +108,10 @@ public static class WebApplicationExtensions
.AddScoped<AuthService>()
.AddScoped<KeyCacheService>()
.AddScoped<RemoteAuthService>()
// Background job classes
.AddTransient<AvatarUpdateJob>();
.AddScoped<ObjectStorageService>()
// Transient jobs
.AddTransient<MemberAvatarUpdateInvocable>()
.AddTransient<UserAvatarUpdateInvocable>();
public static IServiceCollection AddCustomMiddleware(this IServiceCollection services) => services
.AddScoped<ErrorHandlerMiddleware>()
@ -122,6 +127,8 @@ public static class WebApplicationExtensions
{
await BuildInfo.ReadBuildInfo();
app.Services.ConfigureQueue().LogQueuedTaskProgress(app.Services.GetRequiredService<ILogger<IQueue>>());
await using var scope = app.Services.CreateAsyncScope();
var logger = scope.ServiceProvider.GetRequiredService<ILogger>().ForContext<WebApplication>();
var db = scope.ServiceProvider.GetRequiredService<DatabaseContext>();