perf: add blockee cache
This commit is contained in:
parent
a9d0d61d59
commit
f4d8f82239
7 changed files with 52 additions and 13 deletions
|
@ -9,6 +9,7 @@ import {
|
|||
ChannelFollowingsCache,
|
||||
InstanceMutingsCache,
|
||||
LocalFollowingsCache,
|
||||
UserBlockedCache,
|
||||
UserMutingsCache,
|
||||
userWordMuteCache,
|
||||
} from "@/misc/cache.js";
|
||||
|
@ -466,3 +467,18 @@ export async function filterMutedNote(
|
|||
|
||||
return notes.filter((note) => !getWordHardMute(note, user, mutedWords));
|
||||
}
|
||||
|
||||
export async function filterBlockedUser(
|
||||
notes: ScyllaNote[],
|
||||
user: { id: User["id"] },
|
||||
): Promise<ScyllaNote[]> {
|
||||
const cache = await UserBlockedCache.init(user.id);
|
||||
const blockerIds = await cache.getAll();
|
||||
|
||||
return notes.filter(
|
||||
(note) =>
|
||||
!blockerIds.includes(note.userId) &&
|
||||
!(note.replyUserId && blockerIds.includes(note.replyUserId)) &&
|
||||
!(note.renoteUserId && blockerIds.includes(note.renoteUserId)),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import { redisClient } from "@/db/redis.js";
|
|||
import { encode, decode } from "msgpackr";
|
||||
import { ChainableCommander } from "ioredis";
|
||||
import {
|
||||
Blockings,
|
||||
ChannelFollowings,
|
||||
Followings,
|
||||
MutedNotes,
|
||||
|
@ -380,4 +381,23 @@ export class InstanceMutingsCache extends SetCache {
|
|||
}
|
||||
}
|
||||
|
||||
export class UserBlockedCache extends SetCache {
|
||||
private constructor(userId: string) {
|
||||
const fetcher = () =>
|
||||
Blockings.find({
|
||||
select: ["blockerId"],
|
||||
where: { blockeeId: userId },
|
||||
}).then((blocks) => blocks.map(({ blockerId }) => blockerId));
|
||||
|
||||
super("blocked", userId, fetcher);
|
||||
}
|
||||
|
||||
public static async init(userId: string): Promise<UserBlockedCache> {
|
||||
const cache = new UserBlockedCache(userId);
|
||||
await cache.fetch();
|
||||
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
|
||||
export const userWordMuteCache = new Cache<string[][]>("mutedWord", 60 * 30);
|
||||
|
|
|
@ -4,6 +4,7 @@ import { ApiError } from "../../error.js";
|
|||
import { getUser } from "../../common/getters.js";
|
||||
import { Blockings, NoteWatchings, Users } from "@/models/index.js";
|
||||
import { HOUR } from "@/const.js";
|
||||
import { UserBlockedCache } from "@/misc/cache.js";
|
||||
|
||||
export const meta = {
|
||||
tags: ["account"],
|
||||
|
@ -69,12 +70,8 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
});
|
||||
|
||||
// Check if already blocking
|
||||
const exist = await Blockings.exist({
|
||||
where: {
|
||||
blockerId: blocker.id,
|
||||
blockeeId: blockee.id,
|
||||
},
|
||||
});
|
||||
const cache = await UserBlockedCache.init(blockee.id);
|
||||
const exist = await cache.has(blocker.id);
|
||||
|
||||
if (exist) {
|
||||
throw new ApiError(meta.errors.alreadyBlocking);
|
||||
|
|
|
@ -4,6 +4,7 @@ import { ApiError } from "../../error.js";
|
|||
import { getUser } from "../../common/getters.js";
|
||||
import { Blockings, Users } from "@/models/index.js";
|
||||
import { HOUR } from "@/const.js";
|
||||
import { UserBlockedCache } from "@/misc/cache.js";
|
||||
|
||||
export const meta = {
|
||||
tags: ["account"],
|
||||
|
@ -69,12 +70,8 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
});
|
||||
|
||||
// Check not blocking
|
||||
const exist = await Blockings.exist({
|
||||
where: {
|
||||
blockerId: blocker.id,
|
||||
blockeeId: blockee.id,
|
||||
},
|
||||
});
|
||||
const cache = await UserBlockedCache.init(blockee.id);
|
||||
const exist = await cache.has(blocker.id);
|
||||
|
||||
if (!exist) {
|
||||
throw new ApiError(meta.errors.notBlocking);
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
execTimelineQuery,
|
||||
filterMutedUser,
|
||||
filterMutedNote,
|
||||
filterBlockedUser,
|
||||
} from "@/db/scylla.js";
|
||||
import { ChannelFollowingsCache, LocalFollowingsCache } from "@/misc/cache.js";
|
||||
|
||||
|
@ -90,6 +91,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
filtered = await filterVisibility(filtered, user, followingUserIds);
|
||||
filtered = await filterMutedUser(filtered, user);
|
||||
filtered = await filterMutedNote(filtered, user);
|
||||
filtered = await filterBlockedUser(filtered, user);
|
||||
return filtered;
|
||||
};
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import { genId } from "@/misc/gen-id.js";
|
|||
import { IdentifiableError } from "@/misc/identifiable-error.js";
|
||||
import { getActiveWebhooks } from "@/misc/webhook-cache.js";
|
||||
import { webhookDeliver } from "@/queue/index.js";
|
||||
import { UserBlockedCache } from "@/misc/cache";
|
||||
|
||||
export default async function (blocker: User, blockee: User) {
|
||||
await Promise.all([
|
||||
|
@ -41,6 +42,9 @@ export default async function (blocker: User, blockee: User) {
|
|||
|
||||
await Blockings.insert(blocking);
|
||||
|
||||
const cache = await UserBlockedCache.init(blockee.id);
|
||||
await cache.add(blocker.id);
|
||||
|
||||
if (Users.isLocalUser(blocker) && Users.isRemoteUser(blockee)) {
|
||||
const content = renderActivity(renderBlock(blocking));
|
||||
deliver(blocker, content, blockee.inbox);
|
||||
|
|
|
@ -4,8 +4,8 @@ import renderUndo from "@/remote/activitypub/renderer/undo.js";
|
|||
import { deliver } from "@/queue/index.js";
|
||||
import Logger from "../logger.js";
|
||||
import type { CacheableUser } from "@/models/entities/user.js";
|
||||
import { User } from "@/models/entities/user.js";
|
||||
import { Blockings, Users } from "@/models/index.js";
|
||||
import { UserBlockedCache } from "@/misc/cache.js";
|
||||
|
||||
const logger = new Logger("blocking/delete");
|
||||
|
||||
|
@ -15,6 +15,9 @@ export default async function (blocker: CacheableUser, blockee: CacheableUser) {
|
|||
blockeeId: blockee.id,
|
||||
});
|
||||
|
||||
const cache = await UserBlockedCache.init(blockee.id);
|
||||
await cache.delete(blocker.id);
|
||||
|
||||
if (blocking == null) {
|
||||
logger.warn(
|
||||
"ブロック解除がリクエストされましたがブロックしていませんでした",
|
||||
|
|
Loading…
Reference in a new issue