server: refactor prefetchEmojis

Exiting earlier might slightly improve performance.
This commit is contained in:
Johann150 2022-11-13 18:24:15 +01:00
parent 8d6476af2a
commit 131c12a30b
Signed by untrusted user: Johann150
GPG key ID: 9EE6577A2A06F8F1

View file

@ -11,7 +11,7 @@ import { decodeReaction } from './reaction-lib.js';
const cache = new Cache<Emoji | null>(1000 * 60 * 60 * 12);
/**
*
* Information needed to attach in ActivityPub
*/
type PopulatedEmoji = {
name: string;
@ -36,17 +36,16 @@ function parseEmojiStr(emojiName: string, noteUserHost: string | null) {
const name = match[1];
// ホスト正規化
const host = toPunyNullable(normalizeHost(match[2], noteUserHost));
return { name, host };
}
/**
*
* @param emojiName (:, @. (decodeReactionで可能))
* @param noteUserHost
* @returns , nullは未マッチを意味する
* Resolve emoji information from ActivityPub attachment.
* @param emojiName custom emoji names attached to notes, user profiles or in rections. Colons should not be included. Localhost is denote by @. (see also `decodeReaction`)
* @param noteUserHost host that the content is from, to default to
* @returns emoji information. `null` means not found.
*/
export async function populateEmoji(emojiName: string, noteUserHost: string | null): Promise<PopulatedEmoji | null> {
const { name, host } = parseEmojiStr(emojiName, noteUserHost);
@ -72,7 +71,7 @@ export async function populateEmoji(emojiName: string, noteUserHost: string | nu
}
/**
* (, )
* Retrieve list of emojis from the cache. Uncached emoji are dropped.
*/
export async function populateEmojis(emojiNames: string[], noteUserHost: string | null): Promise<PopulatedEmoji[]> {
const emojis = await Promise.all(emojiNames.map(x => populateEmoji(x, noteUserHost)));
@ -103,11 +102,17 @@ export function aggregateNoteEmojis(notes: Note[]) {
}
/**
*
* Query list of emojis in bulk and add them to the cache.
*/
export async function prefetchEmojis(emojis: { name: string; host: string | null; }[]): Promise<void> {
const notCachedEmojis = emojis.filter(emoji => cache.get(`${emoji.name} ${emoji.host}`) == null);
// check if there even are any uncached emoji to handle
if (notCachedEmojis.length === 0) return;
// query all uncached emoji
const emojisQuery: any[] = [];
// group by hosts to try to reduce query size
const hosts = new Set(notCachedEmojis.map(e => e.host));
for (const host of hosts) {
emojisQuery.push({
@ -115,11 +120,14 @@ export async function prefetchEmojis(emojis: { name: string; host: string | null
host: host ?? IsNull(),
});
}
const _emojis = emojisQuery.length > 0 ? await Emojis.find({
await Emojis.find({
where: emojisQuery,
select: ['name', 'host', 'originalUrl', 'publicUrl'],
}) : [];
for (const emoji of _emojis) {
cache.set(`${emoji.name} ${emoji.host}`, emoji);
}
}).then(emojis => {
// store all emojis into the cache
emojis.forEach(emoji => {
cache.set(`${emoji.name} ${emoji.host}`, emoji);
});
});
}