[backend/api] Improve notifications endpoint performance when rendering multiple custom emojis
This commit is contained in:
parent
1af21062fb
commit
ccf93a06aa
1 changed files with 32 additions and 6 deletions
|
@ -1,8 +1,11 @@
|
||||||
using Iceshrimp.Backend.Core.Configuration;
|
using Iceshrimp.Backend.Core.Configuration;
|
||||||
|
using Iceshrimp.Backend.Core.Database;
|
||||||
using Iceshrimp.Backend.Core.Database.Tables;
|
using Iceshrimp.Backend.Core.Database.Tables;
|
||||||
using Iceshrimp.Backend.Core.Extensions;
|
using Iceshrimp.Backend.Core.Extensions;
|
||||||
using Iceshrimp.Backend.Core.Services;
|
using Iceshrimp.Backend.Core.Services;
|
||||||
|
using Iceshrimp.EntityFrameworkCore.Extensions;
|
||||||
using Iceshrimp.Shared.Schemas.Web;
|
using Iceshrimp.Shared.Schemas.Web;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using static Iceshrimp.Shared.Schemas.Web.NotificationResponse;
|
using static Iceshrimp.Shared.Schemas.Web.NotificationResponse;
|
||||||
|
|
||||||
|
@ -12,7 +15,7 @@ public class NotificationRenderer(
|
||||||
IOptions<Config.InstanceSection> instance,
|
IOptions<Config.InstanceSection> instance,
|
||||||
UserRenderer userRenderer,
|
UserRenderer userRenderer,
|
||||||
NoteRenderer noteRenderer,
|
NoteRenderer noteRenderer,
|
||||||
EmojiService emojiSvc
|
DatabaseContext db
|
||||||
) : IScopedService
|
) : IScopedService
|
||||||
{
|
{
|
||||||
private static NotificationResponse Render(Notification notification, NotificationRendererDto data)
|
private static NotificationResponse Render(Notification notification, NotificationRendererDto data)
|
||||||
|
@ -114,21 +117,44 @@ public class NotificationRenderer(
|
||||||
Sensitive = false
|
Sensitive = false
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
var custom = reactions.Where(EmojiService.IsCustomEmoji).ToArray();
|
|
||||||
|
var custom = reactions.Where(EmojiService.IsCustomEmoji)
|
||||||
|
.Select(p =>
|
||||||
|
{
|
||||||
|
var parts = p.Trim(':').Split('@');
|
||||||
|
return (name: parts[0], host: parts.Length > 1 ? parts[1] : null);
|
||||||
|
})
|
||||||
|
.Distinct()
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
var expr = ExpressionExtensions.False<Emoji>();
|
||||||
|
expr = custom.Aggregate(expr, (current, part) => current.Or(p => p.Name == part.name && p.Host == part.host));
|
||||||
|
|
||||||
|
// https://github.com/dotnet/efcore/issues/31492
|
||||||
|
var emojiUrls = await db.Emojis
|
||||||
|
.Where(expr)
|
||||||
|
.Select(e => new
|
||||||
|
{
|
||||||
|
Name = $":{e.Name}{(e.Host != null ? "@" + e.Host : "")}:",
|
||||||
|
Url = e.GetAccessUrl(instance.Value),
|
||||||
|
e.Sensitive
|
||||||
|
})
|
||||||
|
.ToDictionaryAsync(e => e.Name, e => new { e.Url, e.Sensitive });
|
||||||
|
|
||||||
foreach (var s in custom)
|
foreach (var s in custom)
|
||||||
{
|
{
|
||||||
var emoji = await emojiSvc.ResolveEmojiAsync(s);
|
var name = s.host != null ? $":{s.name}@{s.host}:" : $":{s.name}:";
|
||||||
|
emojiUrls.TryGetValue(name, out var emoji);
|
||||||
var reaction = emoji != null
|
var reaction = emoji != null
|
||||||
? new ReactionResponse
|
? new ReactionResponse
|
||||||
{
|
{
|
||||||
Name = s,
|
Name = name,
|
||||||
Url = emoji.GetAccessUrl(instance.Value),
|
Url = emoji.Url,
|
||||||
Sensitive = emoji.Sensitive
|
Sensitive = emoji.Sensitive
|
||||||
}
|
}
|
||||||
: new ReactionResponse
|
: new ReactionResponse
|
||||||
{
|
{
|
||||||
Name = s,
|
Name = name,
|
||||||
Url = null,
|
Url = null,
|
||||||
Sensitive = false
|
Sensitive = false
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue