perf: cache acct
This commit is contained in:
parent
df71ee65b2
commit
df4cf7822e
3 changed files with 29 additions and 14 deletions
|
@ -140,7 +140,7 @@ export class Cache<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SetCache {
|
export class SetCache {
|
||||||
private readonly key: string;
|
private readonly key: string;
|
||||||
private readonly fetchedKey: string;
|
private readonly fetchedKey: string;
|
||||||
private readonly fetcher: () => Promise<string[]>;
|
private readonly fetcher: () => Promise<string[]>;
|
||||||
|
@ -198,7 +198,7 @@ class SetCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class HashCache {
|
export class HashCache {
|
||||||
private readonly key: string;
|
private readonly key: string;
|
||||||
private readonly fetchedKey: string;
|
private readonly fetchedKey: string;
|
||||||
private readonly fetcher: () => Promise<Map<string, string>>;
|
private readonly fetcher: () => Promise<Map<string, string>>;
|
||||||
|
|
|
@ -34,6 +34,10 @@ import { initializeStreamingServer } from "./api/streaming.js";
|
||||||
import { koaBody } from "koa-body";
|
import { koaBody } from "koa-body";
|
||||||
import removeTrailingSlash from "koa-remove-trailing-slashes";
|
import removeTrailingSlash from "koa-remove-trailing-slashes";
|
||||||
import { v4 as uuid } from "uuid";
|
import { v4 as uuid } from "uuid";
|
||||||
|
import {
|
||||||
|
acctToUserIdCache,
|
||||||
|
userDenormalizedCache,
|
||||||
|
} from "@/services/user-cache.js";
|
||||||
|
|
||||||
export const serverLogger = new Logger("server", "gray", false);
|
export const serverLogger = new Logger("server", "gray", false);
|
||||||
|
|
||||||
|
@ -109,19 +113,29 @@ router.use(wellKnown.routes());
|
||||||
|
|
||||||
router.get("/avatar/@:acct", async (ctx) => {
|
router.get("/avatar/@:acct", async (ctx) => {
|
||||||
const { username, host } = Acct.parse(ctx.params.acct);
|
const { username, host } = Acct.parse(ctx.params.acct);
|
||||||
const user = await Users.findOne({
|
const userId = await acctToUserIdCache.fetchMaybe(
|
||||||
where: {
|
`${username}@${host ?? config.host}`,
|
||||||
usernameLower: username.toLowerCase(),
|
() =>
|
||||||
host: host == null || host === config.host ? IsNull() : host,
|
Users.findOne({
|
||||||
isSuspended: false,
|
where: {
|
||||||
},
|
usernameLower: username.toLowerCase(),
|
||||||
relations: ["avatar"],
|
host: !host || host === config.host ? IsNull() : host,
|
||||||
});
|
isSuspended: false,
|
||||||
|
},
|
||||||
|
}).then((user) => user?.id ?? undefined),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
if (user) {
|
if (!userId) {
|
||||||
ctx.redirect(Users.getAvatarUrlSync(user));
|
|
||||||
} else {
|
|
||||||
ctx.redirect("/static-assets/user-unknown.png");
|
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));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import type {
|
||||||
ILocalUser,
|
ILocalUser,
|
||||||
} from "@/models/entities/user.js";
|
} from "@/models/entities/user.js";
|
||||||
import { Users } from "@/models/index.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";
|
import { redisClient, subscriber } from "@/db/redis.js";
|
||||||
|
|
||||||
export const userByIdCache = new Cache<CacheableUser>("userById", 60 * 30);
|
export const userByIdCache = new Cache<CacheableUser>("userById", 60 * 30);
|
||||||
|
@ -24,6 +24,7 @@ export const userDenormalizedCache = new Cache<CacheableUser>(
|
||||||
"userDenormalized",
|
"userDenormalized",
|
||||||
60 * 30,
|
60 * 30,
|
||||||
);
|
);
|
||||||
|
export const acctToUserIdCache = new Cache<string>("acctToUserId", 60 * 60 * 24);
|
||||||
|
|
||||||
subscriber.on("message", async (_, data) => {
|
subscriber.on("message", async (_, data) => {
|
||||||
const obj = JSON.parse(data);
|
const obj = JSON.parse(data);
|
||||||
|
|
Loading…
Reference in a new issue