perf: pass cached values as params
This commit is contained in:
parent
090bb9a2c3
commit
5475383d94
2 changed files with 90 additions and 33 deletions
|
@ -428,13 +428,20 @@ export async function filterReply(
|
||||||
export async function filterMutedUser(
|
export async function filterMutedUser(
|
||||||
notes: ScyllaNote[],
|
notes: ScyllaNote[],
|
||||||
user: { id: User["id"] },
|
user: { id: User["id"] },
|
||||||
|
mutedIds?: User["id"][],
|
||||||
exclude?: User,
|
exclude?: User,
|
||||||
): Promise<ScyllaNote[]> {
|
): Promise<ScyllaNote[]> {
|
||||||
const userCache = await UserMutingsCache.init(user.id);
|
let ids: User["id"][];
|
||||||
let mutedUserIds = await userCache.getAll();
|
|
||||||
|
if (mutedIds) {
|
||||||
|
ids = mutedIds;
|
||||||
|
} else {
|
||||||
|
const userCache = await UserMutingsCache.init(user.id);
|
||||||
|
ids = await userCache.getAll();
|
||||||
|
}
|
||||||
|
|
||||||
if (exclude) {
|
if (exclude) {
|
||||||
mutedUserIds = mutedUserIds.filter((id) => id !== exclude.id);
|
ids = ids.filter((id) => id !== exclude.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const instanceCache = await InstanceMutingsCache.init(user.id);
|
const instanceCache = await InstanceMutingsCache.init(user.id);
|
||||||
|
@ -442,9 +449,9 @@ export async function filterMutedUser(
|
||||||
|
|
||||||
return notes.filter(
|
return notes.filter(
|
||||||
(note) =>
|
(note) =>
|
||||||
!mutedUserIds.includes(note.userId) &&
|
!ids.includes(note.userId) &&
|
||||||
!(note.replyUserId && mutedUserIds.includes(note.replyUserId)) &&
|
!(note.replyUserId && ids.includes(note.replyUserId)) &&
|
||||||
!(note.renoteUserId && mutedUserIds.includes(note.renoteUserId)) &&
|
!(note.renoteUserId && ids.includes(note.renoteUserId)) &&
|
||||||
!(note.userHost && mutedInstances.includes(note.userHost)) &&
|
!(note.userHost && mutedInstances.includes(note.userHost)) &&
|
||||||
!(note.replyUserHost && mutedInstances.includes(note.replyUserHost)) &&
|
!(note.replyUserHost && mutedInstances.includes(note.replyUserHost)) &&
|
||||||
!(note.renoteUserHost && mutedInstances.includes(note.renoteUserHost)),
|
!(note.renoteUserHost && mutedInstances.includes(note.renoteUserHost)),
|
||||||
|
@ -454,44 +461,65 @@ export async function filterMutedUser(
|
||||||
export async function filterMutedNote(
|
export async function filterMutedNote(
|
||||||
notes: ScyllaNote[],
|
notes: ScyllaNote[],
|
||||||
user: { id: User["id"] },
|
user: { id: User["id"] },
|
||||||
|
mutedWords?: string[][],
|
||||||
): Promise<ScyllaNote[]> {
|
): Promise<ScyllaNote[]> {
|
||||||
const mutedWords = await userWordMuteCache.fetchMaybe(user.id, () =>
|
let words = mutedWords;
|
||||||
UserProfiles.findOne({
|
|
||||||
select: ["mutedWords"],
|
|
||||||
where: { userId: user.id },
|
|
||||||
}).then((profile) => profile?.mutedWords),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!mutedWords) {
|
if (!words) {
|
||||||
return notes;
|
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(
|
export async function filterBlockedUser(
|
||||||
notes: ScyllaNote[],
|
notes: ScyllaNote[],
|
||||||
user: { id: User["id"] },
|
user: { id: User["id"] },
|
||||||
|
blockerIds?: User["id"][],
|
||||||
): Promise<ScyllaNote[]> {
|
): Promise<ScyllaNote[]> {
|
||||||
const cache = await UserBlockedCache.init(user.id);
|
let ids: User["id"][];
|
||||||
const blockerIds = await cache.getAll();
|
|
||||||
|
if (blockerIds) {
|
||||||
|
ids = blockerIds;
|
||||||
|
} else {
|
||||||
|
const cache = await UserBlockedCache.init(user.id);
|
||||||
|
ids = await cache.getAll();
|
||||||
|
}
|
||||||
|
|
||||||
return notes.filter(
|
return notes.filter(
|
||||||
(note) =>
|
(note) =>
|
||||||
!blockerIds.includes(note.userId) &&
|
!ids.includes(note.userId) &&
|
||||||
!(note.replyUserId && blockerIds.includes(note.replyUserId)) &&
|
!(note.replyUserId && ids.includes(note.replyUserId)) &&
|
||||||
!(note.renoteUserId && blockerIds.includes(note.renoteUserId)),
|
!(note.renoteUserId && ids.includes(note.renoteUserId)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function filterMutedRenotes(
|
export async function filterMutedRenotes(
|
||||||
notes: ScyllaNote[],
|
notes: ScyllaNote[],
|
||||||
user: { id: User["id"] },
|
user: { id: User["id"] },
|
||||||
|
muteeIds?: User["id"][],
|
||||||
): Promise<ScyllaNote[]> {
|
): Promise<ScyllaNote[]> {
|
||||||
const cache = await RenoteMutingsCache.init(user.id);
|
let ids: User["id"][];
|
||||||
const muteeIds = await cache.getAll();
|
|
||||||
|
if (muteeIds) {
|
||||||
|
ids = muteeIds;
|
||||||
|
} else {
|
||||||
|
const cache = await RenoteMutingsCache.init(user.id);
|
||||||
|
ids = await cache.getAll();
|
||||||
|
}
|
||||||
|
|
||||||
return notes.filter(
|
return notes.filter(
|
||||||
(note) => note.text || !note.renoteId || !muteeIds.includes(note.userId),
|
(note) => note.text || !note.renoteId || !ids.includes(note.userId),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Brackets } from "typeorm";
|
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 { activeUsersChart } from "@/services/chart/index.js";
|
||||||
import define from "../../define.js";
|
import define from "../../define.js";
|
||||||
import { makePaginationQuery } from "../../common/make-pagination-query.js";
|
import { makePaginationQuery } from "../../common/make-pagination-query.js";
|
||||||
|
@ -23,7 +23,7 @@ import {
|
||||||
filterBlockedUser,
|
filterBlockedUser,
|
||||||
filterMutedRenotes,
|
filterMutedRenotes,
|
||||||
} from "@/db/scylla.js";
|
} 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 = {
|
export const meta = {
|
||||||
tags: ["notes"],
|
tags: ["notes"],
|
||||||
|
@ -79,21 +79,54 @@ export const paramDef = {
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const followingsCache = await LocalFollowingsCache.init(user.id);
|
const followingsCache = await LocalFollowingsCache.init(user.id);
|
||||||
|
|
||||||
|
process.nextTick(() => {
|
||||||
|
activeUsersChart.read(user);
|
||||||
|
});
|
||||||
|
|
||||||
if (scyllaClient) {
|
if (scyllaClient) {
|
||||||
const channelCache = await ChannelFollowingsCache.init(user.id);
|
const channelCache = await ChannelFollowingsCache.init(user.id);
|
||||||
const followingChannelIds = await channelCache.getAll();
|
const followingChannelIds = await channelCache.getAll();
|
||||||
const followingUserIds = await followingsCache.getAll();
|
const followingUserIds = await followingsCache.getAll();
|
||||||
const validUserIds = [user.id].concat(followingUserIds);
|
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[]) => {
|
const filter = async (notes: ScyllaNote[]) => {
|
||||||
let filtered = notes.filter((n) => validUserIds.includes(n.userId));
|
let filtered = notes.filter((n) => validUserIds.includes(n.userId));
|
||||||
filtered = await filterChannel(filtered, user, followingChannelIds);
|
filtered = await filterChannel(filtered, user, followingChannelIds);
|
||||||
filtered = await filterReply(filtered, ps.withReplies, user);
|
filtered = await filterReply(filtered, ps.withReplies, user);
|
||||||
filtered = await filterVisibility(filtered, user, followingUserIds);
|
filtered = await filterVisibility(filtered, user, followingUserIds);
|
||||||
filtered = await filterMutedUser(filtered, user);
|
filtered = await filterMutedUser(filtered, user, mutedUserIds);
|
||||||
filtered = await filterMutedNote(filtered, user);
|
filtered = await filterMutedNote(filtered, user, mutedWords ?? []);
|
||||||
filtered = await filterBlockedUser(filtered, user);
|
filtered = await filterBlockedUser(filtered, user, blockerIds);
|
||||||
filtered = await filterMutedRenotes(filtered, user);
|
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;
|
return filtered;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -183,10 +216,6 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
query.andWhere("note.visibility != 'hidden'");
|
query.andWhere("note.visibility != 'hidden'");
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
process.nextTick(() => {
|
|
||||||
activeUsersChart.read(user);
|
|
||||||
});
|
|
||||||
|
|
||||||
// We fetch more than requested because some may be filtered out, and if there's less than
|
// We fetch more than requested because some may be filtered out, and if there's less than
|
||||||
// requested, the pagination stops.
|
// requested, the pagination stops.
|
||||||
const found = [];
|
const found = [];
|
||||||
|
|
Loading…
Reference in a new issue