Revert "perf: prepare scylladb config and use cache for packing user"

This reverts commit 9c65f0078b.
This commit is contained in:
Namekuji 2023-07-19 10:09:32 -04:00
parent abad503a24
commit a047e642f1
No known key found for this signature in database
GPG key ID: 1D62332C07FBA532
11 changed files with 33 additions and 100 deletions

View file

@ -67,7 +67,7 @@ redis:
#db: 1
#user: default
# ┌────────────────────────────
# ┌────────────────────────────
#───┘ Cache server configuration └─────────────────────────────────────
# A Redis-compatible server (DragonflyDB, Keydb, Redis) for caching
@ -81,14 +81,6 @@ redis:
#prefix: example-prefix
#db: 1
# ┌────────────────────────┐
#───┘ ScyllaDB configuration └─────────────────────────────────────
# scylla:
# nodes: ['localhost:9042']
# keyspace: calckey
# replicationFactor: 1
# Please configure either MeiliSearch *or* Sonic.
# If both MeiliSearch and Sonic configurations are present, MeiliSearch will take precedence.

View file

@ -53,7 +53,6 @@
"bull": "4.10.4",
"cacheable-lookup": "7.0.0",
"calckey-js": "workspace:*",
"cassandra-driver": "^4.6.4",
"cbor": "8.1.0",
"chalk": "5.3.0",
"chalk-template": "0.4.0",

View file

@ -16,11 +16,6 @@ export type Source = {
disableCache?: boolean;
extra?: { [x: string]: string };
};
scylla?: {
nodes: string[];
keyspace: string;
replicationFactor: number;
},
redis: {
host: string;
port: number;

View file

@ -1,28 +0,0 @@
import config from "@/config/index.js";
import { Client } from "cassandra-driver";
function newClient(): Client | null {
if (!config.scylla) {
return null;
}
return new Client({
contactPoints: config.scylla.nodes,
keyspace: config.scylla.keyspace,
});
}
export const scyllaClient = newClient();
export const prepared = {
timeline: {
insert: "",
select: "",
delete: "",
},
notification: {
insert: "",
select: "",
delete: "",
}
}

View file

@ -37,7 +37,6 @@ import {
UserSecurityKeys,
} from "../index.js";
import type { Instance } from "../entities/instance.js";
import { userByIdCache } from "@/services/user-cache.js";
const userInstanceCache = new Cache<Instance | null>(
"userInstance",
@ -383,24 +382,23 @@ export const UserRepository = db.getRepository(User).extend({
options,
);
let id: string;
let user: User;
if (typeof src === "object") {
id = src.id;
user = src;
if (src.avatar === undefined && src.avatarId)
src.avatar = (await DriveFiles.findOneBy({ id: src.avatarId })) ?? null;
if (src.banner === undefined && src.bannerId)
src.banner = (await DriveFiles.findOneBy({ id: src.bannerId })) ?? null;
} else {
id = src;
}
const user = await userByIdCache.fetch(id, () =>
this.findOneOrFail({
where: { id },
user = await this.findOneOrFail({
where: { id: src },
relations: {
avatar: true,
banner: true,
},
}),
true,
);
});
}
const meId = me ? me.id : null;
const isMe = meId === user.id;

View file

@ -128,12 +128,8 @@ export default class DbResolver {
(await userByIdCache.fetchMaybe(
parsed.id,
() =>
Users.findOne({
where: { id: parsed.id },
relations: {
avatar: true,
banner: true,
},
Users.findOneBy({
id: parsed.id,
}).then((x) => x ?? undefined),
true,
)) ?? null
@ -177,11 +173,7 @@ export default class DbResolver {
return {
user: (await userByIdCache.fetch(
key.userId,
() =>
Users.findOneOrFail({
where: { id: key.userId },
relations: { avatar: true, banner: true },
}),
() => Users.findOneByOrFail({ id: key.userId }),
true,
)) as CacheableRemoteUser,
key,

View file

@ -14,8 +14,6 @@ import { normalizeForSearch } from "@/misc/normalize-for-search.js";
import { langmap } from "@/misc/langmap.js";
import { ApiError } from "../../error.js";
import define from "../../define.js";
import { userByIdCache } from "@/services/user-cache.js";
import type { DriveFile } from "@/models/entities/drive-file.js";
export const meta = {
tags: ["account"],
@ -206,9 +204,8 @@ export default define(meta, paramDef, async (ps, _user, token) => {
if (ps.emailNotificationTypes !== undefined)
profileUpdates.emailNotificationTypes = ps.emailNotificationTypes;
let avatar: DriveFile | null = null;
if (ps.avatarId) {
avatar = await DriveFiles.findOneBy({ id: ps.avatarId });
const avatar = await DriveFiles.findOneBy({ id: ps.avatarId });
if (avatar == null || avatar.userId !== user.id)
throw new ApiError(meta.errors.noSuchAvatar);
@ -216,9 +213,8 @@ export default define(meta, paramDef, async (ps, _user, token) => {
throw new ApiError(meta.errors.avatarNotAnImage);
}
let banner: DriveFile | null = null;
if (ps.bannerId) {
banner = await DriveFiles.findOneBy({ id: ps.bannerId });
const banner = await DriveFiles.findOneBy({ id: ps.bannerId });
if (banner == null || banner.userId !== user.id)
throw new ApiError(meta.errors.noSuchBanner);
@ -282,10 +278,7 @@ export default define(meta, paramDef, async (ps, _user, token) => {
updateUsertags(user, tags);
//#endregion
if (Object.keys(updates).length > 0) {
await Users.update(user.id, updates);
await userByIdCache.set(user.id, { ...user, ...updates, avatar, banner });
}
if (Object.keys(updates).length > 0) await Users.update(user.id, updates);
if (Object.keys(profileUpdates).length > 0)
await UserProfiles.update(user.id, profileUpdates);

View file

@ -89,10 +89,17 @@ export default define(meta, paramDef, async (ps, user) => {
ps.untilDate,
)
.andWhere("(note.visibility = 'public') AND (note.userHost IS NULL)")
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
// TODO: Use materialized view of postgres as much for non-denormalizable columns as possible.
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
generateChannelQuery(query, user);
generateRepliesQuery(query, ps.withReplies, user);

View file

@ -92,10 +92,16 @@ export default define(meta, paramDef, async (ps, user) => {
}),
)
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner")
.setParameters(followingQuery.getParameters());
generateChannelQuery(query, user);

View file

@ -40,10 +40,7 @@ subscriber.on("message", async (_, data) => {
case "userChangeSilencedState":
case "userChangeModeratorState":
case "remoteUserUpdated": {
const user = await Users.findOneOrFail({
where: { id: body.id },
relations: { avatar: true, banner: true },
});
const user = await Users.findOneByOrFail({ id: body.id });
await userByIdCache.set(user.id, user);
const trans = redisClient.multi();
for (const [k, v] of (await uriPersonCache.getAll()).entries()) {

View file

@ -159,9 +159,6 @@ importers:
calckey-js:
specifier: workspace:*
version: link:../calckey-js
cassandra-driver:
specifier: ^4.6.4
version: 4.6.4
cbor:
specifier: 8.1.0
version: 8.1.0
@ -6223,16 +6220,6 @@ packages:
/caseless@0.12.0:
resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
/cassandra-driver@4.6.4:
resolution: {integrity: sha512-SksbIK0cZ2QZRx8ti7w+PnLqldyY+6kU2gRWFChwXFTtrD/ce8cQICDEHxyPwx+DeILwRnMrPf9cjUGizYw9Vg==}
engines: {node: '>=8'}
dependencies:
'@types/long': 4.0.2
'@types/node': 20.4.1
adm-zip: 0.5.10
long: 2.4.0
dev: false
/cbor@8.1.0:
resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==}
engines: {node: '>=12.19'}
@ -12900,11 +12887,6 @@ packages:
wrap-ansi: 6.2.0
dev: true
/long@2.4.0:
resolution: {integrity: sha512-ijUtjmO/n2A5PaosNG9ZGDsQ3vxJg7ZW8vsY8Kp0f2yIZWhSJvjmegV7t+9RPQKxKrvj8yKGehhS+po14hPLGQ==}
engines: {node: '>=0.6'}
dev: false
/long@4.0.0:
resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==}
dev: false