diff --git a/extensions/matrix/src/matrix/monitor/handler.ts b/extensions/matrix/src/matrix/monitor/handler.ts index c73272660b7..17e90b6fd53 100644 --- a/extensions/matrix/src/matrix/monitor/handler.ts +++ b/extensions/matrix/src/matrix/monitor/handler.ts @@ -76,6 +76,7 @@ export type MatrixMonitorHandlerParams = { }; getRoomInfo: ( roomId: string, + opts?: { includeAliases?: boolean }, ) => Promise<{ name?: string; canonicalAlias?: string; altAliases: string[] }>; getMemberDisplayName: (roomId: string, userId: string) => Promise; }; @@ -256,15 +257,6 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam selfUserId, }); const isRoom = !isDirectMessage; - let roomInfoPromise: Promise<{ - name?: string; - canonicalAlias?: string; - altAliases: string[]; - }> | null = null; - const getResolvedRoomInfo = async () => { - roomInfoPromise ??= getRoomInfo(roomId); - return await roomInfoPromise; - }; if (isRoom && groupPolicy === "disabled") { return; @@ -272,7 +264,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam const roomInfoForConfig = isRoom && roomsConfig && Object.keys(roomsConfig).some((key) => key.trim().startsWith("#")) - ? await getResolvedRoomInfo() + ? await getRoomInfo(roomId, { includeAliases: true }) : undefined; const roomAliasesForConfig = roomInfoForConfig ? [roomInfoForConfig.canonicalAlias ?? "", ...roomInfoForConfig.altAliases].filter(Boolean) @@ -560,7 +552,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam return; } const senderName = await getSenderName(); - const roomInfo = isRoom ? await getResolvedRoomInfo() : undefined; + const roomInfo = isRoom ? await getRoomInfo(roomId) : undefined; const roomName = roomInfo?.name; const messageId = event.event_id ?? ""; diff --git a/extensions/matrix/src/matrix/monitor/room-info.test.ts b/extensions/matrix/src/matrix/monitor/room-info.test.ts index ec27c6c4880..0cfb3c4ab1c 100644 --- a/extensions/matrix/src/matrix/monitor/room-info.test.ts +++ b/extensions/matrix/src/matrix/monitor/room-info.test.ts @@ -31,12 +31,14 @@ function createClientStub() { } describe("createMatrixRoomInfoResolver", () => { - it("caches room info and member display names", async () => { + it("caches room names and member display names, and loads aliases only on demand", async () => { const client = createClientStub(); const resolver = createMatrixRoomInfoResolver(client); await resolver.getRoomInfo("!room:example.org"); await resolver.getRoomInfo("!room:example.org"); + await resolver.getRoomInfo("!room:example.org", { includeAliases: true }); + await resolver.getRoomInfo("!room:example.org", { includeAliases: true }); await resolver.getMemberDisplayName("!room:example.org", "@alice:example.org"); await resolver.getMemberDisplayName("!room:example.org", "@alice:example.org"); @@ -57,6 +59,6 @@ describe("createMatrixRoomInfoResolver", () => { } await resolver.getMemberDisplayName("!room:example.org", "@user-0:example.org"); - expect(client.getRoomStateEvent).toHaveBeenCalledTimes(6150); + expect(client.getRoomStateEvent).toHaveBeenCalledTimes(5124); }); }); diff --git a/extensions/matrix/src/matrix/monitor/room-info.ts b/extensions/matrix/src/matrix/monitor/room-info.ts index 2b5a01454d0..cbfc4b173b5 100644 --- a/extensions/matrix/src/matrix/monitor/room-info.ts +++ b/extensions/matrix/src/matrix/monitor/room-info.ts @@ -20,17 +20,15 @@ function rememberBounded(map: Map, key: string, value: T, maxEntri } export function createMatrixRoomInfoResolver(client: MatrixClient) { - const roomInfoCache = new Map(); + const roomNameCache = new Map(); + const roomAliasCache = new Map>(); const memberDisplayNameCache = new Map(); - const getRoomInfo = async (roomId: string): Promise => { - const cached = roomInfoCache.get(roomId); - if (cached) { - return cached; + const getRoomName = async (roomId: string): Promise => { + if (roomNameCache.has(roomId)) { + return roomNameCache.get(roomId); } let name: string | undefined; - let canonicalAlias: string | undefined; - let altAliases: string[] = []; try { const nameState = await client.getRoomStateEvent(roomId, "m.room.name", "").catch(() => null); if (nameState && typeof nameState.name === "string") { @@ -39,6 +37,19 @@ export function createMatrixRoomInfoResolver(client: MatrixClient) { } catch { // ignore } + rememberBounded(roomNameCache, roomId, name, MAX_TRACKED_ROOM_INFO); + return name; + }; + + const getRoomAliases = async ( + roomId: string, + ): Promise> => { + const cached = roomAliasCache.get(roomId); + if (cached) { + return cached; + } + let canonicalAlias: string | undefined; + let altAliases: string[] = []; try { const aliasState = await client .getRoomStateEvent(roomId, "m.room.canonical_alias", "") @@ -53,11 +64,23 @@ export function createMatrixRoomInfoResolver(client: MatrixClient) { } catch { // ignore } - const info = { name, canonicalAlias, altAliases }; - rememberBounded(roomInfoCache, roomId, info, MAX_TRACKED_ROOM_INFO); + const info = { canonicalAlias, altAliases }; + rememberBounded(roomAliasCache, roomId, info, MAX_TRACKED_ROOM_INFO); return info; }; + const getRoomInfo = async ( + roomId: string, + opts: { includeAliases?: boolean } = {}, + ): Promise => { + const name = await getRoomName(roomId); + if (!opts.includeAliases) { + return { name, altAliases: [] }; + } + const aliases = await getRoomAliases(roomId); + return { name, ...aliases }; + }; + const getMemberDisplayName = async (roomId: string, userId: string): Promise => { const cacheKey = `${roomId}:${userId}`; const cached = memberDisplayNameCache.get(cacheKey);