perf: cache acct

This commit is contained in:
Namekuji 2023-08-07 08:32:29 -04:00
parent df71ee65b2
commit df4cf7822e
No known key found for this signature in database
GPG key ID: 1D62332C07FBA532
3 changed files with 29 additions and 14 deletions

View file

@ -140,7 +140,7 @@ export class Cache<T> {
}
}
class SetCache {
export class SetCache {
private readonly key: string;
private readonly fetchedKey: string;
private readonly fetcher: () => Promise<string[]>;
@ -198,7 +198,7 @@ class SetCache {
}
}
class HashCache {
export class HashCache {
private readonly key: string;
private readonly fetchedKey: string;
private readonly fetcher: () => Promise<Map<string, string>>;

View file

@ -34,6 +34,10 @@ import { initializeStreamingServer } from "./api/streaming.js";
import { koaBody } from "koa-body";
import removeTrailingSlash from "koa-remove-trailing-slashes";
import { v4 as uuid } from "uuid";
import {
acctToUserIdCache,
userDenormalizedCache,
} from "@/services/user-cache.js";
export const serverLogger = new Logger("server", "gray", false);
@ -109,19 +113,29 @@ router.use(wellKnown.routes());
router.get("/avatar/@:acct", async (ctx) => {
const { username, host } = Acct.parse(ctx.params.acct);
const user = await Users.findOne({
where: {
usernameLower: username.toLowerCase(),
host: host == null || host === config.host ? IsNull() : host,
isSuspended: false,
},
relations: ["avatar"],
});
const userId = await acctToUserIdCache.fetchMaybe(
`${username}@${host ?? config.host}`,
() =>
Users.findOne({
where: {
usernameLower: username.toLowerCase(),
host: !host || host === config.host ? IsNull() : host,
isSuspended: false,
},
}).then((user) => user?.id ?? undefined),
true,
);
if (user) {
ctx.redirect(Users.getAvatarUrlSync(user));
} else {
if (!userId) {
ctx.redirect("/static-assets/user-unknown.png");
} else {
const user = await userDenormalizedCache.fetch(userId, () =>
Users.findOneOrFail({
relations: { avatar: true, banner: true },
where: { id: userId },
}),
);
ctx.redirect(Users.getAvatarUrlSync(user));
}
});

View file

@ -4,7 +4,7 @@ import type {
ILocalUser,
} from "@/models/entities/user.js";
import { Users } from "@/models/index.js";
import { Cache } from "@/misc/cache.js";
import { Cache, HashCache } from "@/misc/cache.js";
import { redisClient, subscriber } from "@/db/redis.js";
export const userByIdCache = new Cache<CacheableUser>("userById", 60 * 30);
@ -24,6 +24,7 @@ export const userDenormalizedCache = new Cache<CacheableUser>(
"userDenormalized",
60 * 30,
);
export const acctToUserIdCache = new Cache<string>("acctToUserId", 60 * 60 * 24);
subscriber.on("message", async (_, data) => {
const obj = JSON.parse(data);