perf(telegram): bound forum metadata cache

This commit is contained in:
Ayaan Zaidi
2026-04-23 14:19:41 +05:30
parent 1bd8c5f362
commit 8a078acaa6
2 changed files with 44 additions and 4 deletions

View File

@@ -74,6 +74,20 @@ describe("resolveTelegramForumFlag", () => {
expect(getChat).toHaveBeenCalledTimes(1);
});
it("refreshes cached forum metadata from explicit Telegram updates", async () => {
const getChat = vi.fn(async () => ({ is_forum: true }));
const params = {
chatId: -100654,
chatType: "supergroup" as const,
isGroup: true,
getChat,
};
await expect(resolveTelegramForumFlag(params)).resolves.toBe(true);
await expect(resolveTelegramForumFlag({ ...params, isForum: false })).resolves.toBe(false);
await expect(resolveTelegramForumFlag(params)).resolves.toBe(false);
expect(getChat).toHaveBeenCalledTimes(1);
});
it("returns false when forum lookup is unavailable", async () => {
const getChat = vi.fn(async () => {
throw new Error("lookup failed");

View File

@@ -40,7 +40,26 @@ export {
};
const TELEGRAM_GENERAL_TOPIC_ID = 1;
const telegramForumFlagByChatId = new Map<string, boolean>();
const TELEGRAM_FORUM_FLAG_CACHE_MAX_CHATS = 1024;
const TELEGRAM_FORUM_FLAG_CACHE_TTL_MS = 10 * 60_000;
const telegramForumFlagByChatId = new Map<string, { expiresAtMs: number; isForum: boolean }>();
function cacheTelegramForumFlag(chatId: string | number, isForum: boolean, nowMs = Date.now()) {
const cacheKey = String(chatId);
if (
!telegramForumFlagByChatId.has(cacheKey) &&
telegramForumFlagByChatId.size >= TELEGRAM_FORUM_FLAG_CACHE_MAX_CHATS
) {
const oldestKey = telegramForumFlagByChatId.keys().next().value;
if (oldestKey !== undefined) {
telegramForumFlagByChatId.delete(oldestKey);
}
}
telegramForumFlagByChatId.set(cacheKey, {
expiresAtMs: nowMs + TELEGRAM_FORUM_FLAG_CACHE_TTL_MS,
isForum,
});
}
function hadUnsafeTelegramText(raw: unknown, sanitized: string): boolean {
return typeof raw === "string" && raw.trim().length > 0 && sanitized.trim().length === 0;
@@ -67,19 +86,26 @@ export async function resolveTelegramForumFlag(params: {
getChat?: TelegramGetChat;
}): Promise<boolean> {
if (typeof params.isForum === "boolean") {
if (params.isGroup && params.chatType === "supergroup") {
cacheTelegramForumFlag(params.chatId, params.isForum);
}
return params.isForum;
}
if (!params.isGroup || params.chatType !== "supergroup" || !params.getChat) {
return false;
}
const cacheKey = String(params.chatId);
const nowMs = Date.now();
const cached = telegramForumFlagByChatId.get(cacheKey);
if (cached !== undefined) {
return cached;
if (cached && cached.expiresAtMs > nowMs) {
return cached.isForum;
}
if (cached) {
telegramForumFlagByChatId.delete(cacheKey);
}
try {
const resolved = extractTelegramForumFlag(await params.getChat(params.chatId)) === true;
telegramForumFlagByChatId.set(cacheKey, resolved);
cacheTelegramForumFlag(params.chatId, resolved, nowMs);
return resolved;
} catch {
return false;