perf: pass cached values as params

This commit is contained in:
Namekuji 2023-08-07 06:52:03 -04:00
parent 090bb9a2c3
commit 5475383d94
No known key found for this signature in database
GPG key ID: 1D62332C07FBA532
2 changed files with 90 additions and 33 deletions

View file

@ -428,13 +428,20 @@ export async function filterReply(
export async function filterMutedUser(
notes: ScyllaNote[],
user: { id: User["id"] },
mutedIds?: User["id"][],
exclude?: User,
): Promise<ScyllaNote[]> {
const userCache = await UserMutingsCache.init(user.id);
let mutedUserIds = await userCache.getAll();
let ids: User["id"][];
if (mutedIds) {
ids = mutedIds;
} else {
const userCache = await UserMutingsCache.init(user.id);
ids = await userCache.getAll();
}
if (exclude) {
mutedUserIds = mutedUserIds.filter((id) => id !== exclude.id);
ids = ids.filter((id) => id !== exclude.id);
}
const instanceCache = await InstanceMutingsCache.init(user.id);
@ -442,9 +449,9 @@ export async function filterMutedUser(
return notes.filter(
(note) =>
!mutedUserIds.includes(note.userId) &&
!(note.replyUserId && mutedUserIds.includes(note.replyUserId)) &&
!(note.renoteUserId && mutedUserIds.includes(note.renoteUserId)) &&
!ids.includes(note.userId) &&
!(note.replyUserId && ids.includes(note.replyUserId)) &&
!(note.renoteUserId && ids.includes(note.renoteUserId)) &&
!(note.userHost && mutedInstances.includes(note.userHost)) &&
!(note.replyUserHost && mutedInstances.includes(note.replyUserHost)) &&
!(note.renoteUserHost && mutedInstances.includes(note.renoteUserHost)),
@ -454,44 +461,65 @@ export async function filterMutedUser(
export async function filterMutedNote(
notes: ScyllaNote[],
user: { id: User["id"] },
mutedWords?: string[][],
): Promise<ScyllaNote[]> {
const mutedWords = await userWordMuteCache.fetchMaybe(user.id, () =>
UserProfiles.findOne({
select: ["mutedWords"],
where: { userId: user.id },
}).then((profile) => profile?.mutedWords),
);
let words = mutedWords;
if (!mutedWords) {
return notes;
if (!words) {
words = await userWordMuteCache.fetchMaybe(user.id, () =>
UserProfiles.findOne({
select: ["mutedWords"],
where: { userId: user.id },
}).then((profile) => profile?.mutedWords),
);
}
return notes.filter((note) => !getWordHardMute(note, user, mutedWords));
if (words && words.length > 0) {
return notes.filter(
(note) => !getWordHardMute(note, user, words as string[][]),
);
}
return notes;
}
export async function filterBlockedUser(
notes: ScyllaNote[],
user: { id: User["id"] },
blockerIds?: User["id"][],
): Promise<ScyllaNote[]> {
const cache = await UserBlockedCache.init(user.id);
const blockerIds = await cache.getAll();
let ids: User["id"][];
if (blockerIds) {
ids = blockerIds;
} else {
const cache = await UserBlockedCache.init(user.id);
ids = await cache.getAll();
}
return notes.filter(
(note) =>
!blockerIds.includes(note.userId) &&
!(note.replyUserId && blockerIds.includes(note.replyUserId)) &&
!(note.renoteUserId && blockerIds.includes(note.renoteUserId)),
!ids.includes(note.userId) &&
!(note.replyUserId && ids.includes(note.replyUserId)) &&
!(note.renoteUserId && ids.includes(note.renoteUserId)),
);
}
export async function filterMutedRenotes(
notes: ScyllaNote[],
user: { id: User["id"] },
muteeIds?: User["id"][],
): Promise<ScyllaNote[]> {
const cache = await RenoteMutingsCache.init(user.id);
const muteeIds = await cache.getAll();
let ids: User["id"][];
if (muteeIds) {
ids = muteeIds;
} else {
const cache = await RenoteMutingsCache.init(user.id);
ids = await cache.getAll();
}
return notes.filter(
(note) => note.text || !note.renoteId || !muteeIds.includes(note.userId),
(note) => note.text || !note.renoteId || !ids.includes(note.userId),
);
}

View file

@ -1,5 +1,5 @@
import { Brackets } from "typeorm";
import { Notes, Followings } from "@/models/index.js";
import { Notes, Followings, UserProfiles } from "@/models/index.js";
import { activeUsersChart } from "@/services/chart/index.js";
import define from "../../define.js";
import { makePaginationQuery } from "../../common/make-pagination-query.js";
@ -23,7 +23,7 @@ import {
filterBlockedUser,
filterMutedRenotes,
} from "@/db/scylla.js";
import { ChannelFollowingsCache, LocalFollowingsCache } from "@/misc/cache.js";
import { ChannelFollowingsCache, LocalFollowingsCache, RenoteMutingsCache, UserBlockedCache, UserMutingsCache, userWordMuteCache } from "@/misc/cache.js";
export const meta = {
tags: ["notes"],
@ -79,21 +79,54 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => {
const followingsCache = await LocalFollowingsCache.init(user.id);
process.nextTick(() => {
activeUsersChart.read(user);
});
if (scyllaClient) {
const channelCache = await ChannelFollowingsCache.init(user.id);
const followingChannelIds = await channelCache.getAll();
const followingUserIds = await followingsCache.getAll();
const validUserIds = [user.id].concat(followingUserIds);
const userMutingsCache = await UserMutingsCache.init(user.id);
const mutedUserIds = await userMutingsCache.getAll();
const mutedWords = await userWordMuteCache.fetchMaybe(user.id, () =>
UserProfiles.findOne({
select: ["mutedWords"],
where: { userId: user.id },
}).then((profile) => profile?.mutedWords),
);
const blockedCache = await UserBlockedCache.init(user.id);
const blockerIds = await blockedCache.getAll();
const renoteMutingsCache = await RenoteMutingsCache.init(user.id);
const renoteMutedIds = await renoteMutingsCache.getAll();
const optFilter = (n: ScyllaNote) =>
!n.renoteId || !!n.text || n.files.length > 0 || n.hasPoll;
const filter = async (notes: ScyllaNote[]) => {
let filtered = notes.filter((n) => validUserIds.includes(n.userId));
filtered = await filterChannel(filtered, user, followingChannelIds);
filtered = await filterReply(filtered, ps.withReplies, user);
filtered = await filterVisibility(filtered, user, followingUserIds);
filtered = await filterMutedUser(filtered, user);
filtered = await filterMutedNote(filtered, user);
filtered = await filterBlockedUser(filtered, user);
filtered = await filterMutedRenotes(filtered, user);
filtered = await filterMutedUser(filtered, user, mutedUserIds);
filtered = await filterMutedNote(filtered, user, mutedWords ?? []);
filtered = await filterBlockedUser(filtered, user, blockerIds);
filtered = await filterMutedRenotes(filtered, user, renoteMutedIds);
if (!ps.includeMyRenotes) {
filtered = filtered.filter((n) => n.userId !== user.id || optFilter(n));
}
if (!ps.includeRenotedMyNotes) {
filtered = filtered.filter(
(n) => n.renoteUserId !== user.id || optFilter(n),
);
}
if (!ps.includeLocalRenotes) {
filtered = filtered.filter((n) => n.renoteUserHost || optFilter(n));
}
if (ps.withFiles) {
filtered = filtered.filter((n) => n.files.length > 0);
}
filtered = filtered.filter((n) => n.visibility !== "hidden");
return filtered;
};
@ -183,10 +216,6 @@ export default define(meta, paramDef, async (ps, user) => {
query.andWhere("note.visibility != 'hidden'");
//#endregion
process.nextTick(() => {
activeUsersChart.read(user);
});
// We fetch more than requested because some may be filtered out, and if there's less than
// requested, the pagination stops.
const found = [];