mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-24 16:32:29 +00:00
Matrix: fetch aliases only when needed
This commit is contained in:
@@ -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<string>;
|
||||
};
|
||||
@@ -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 ?? "";
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,17 +20,15 @@ function rememberBounded<T>(map: Map<string, T>, key: string, value: T, maxEntri
|
||||
}
|
||||
|
||||
export function createMatrixRoomInfoResolver(client: MatrixClient) {
|
||||
const roomInfoCache = new Map<string, MatrixRoomInfo>();
|
||||
const roomNameCache = new Map<string, string | undefined>();
|
||||
const roomAliasCache = new Map<string, Pick<MatrixRoomInfo, "canonicalAlias" | "altAliases">>();
|
||||
const memberDisplayNameCache = new Map<string, string>();
|
||||
|
||||
const getRoomInfo = async (roomId: string): Promise<MatrixRoomInfo> => {
|
||||
const cached = roomInfoCache.get(roomId);
|
||||
if (cached) {
|
||||
return cached;
|
||||
const getRoomName = async (roomId: string): Promise<string | undefined> => {
|
||||
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<Pick<MatrixRoomInfo, "canonicalAlias" | "altAliases">> => {
|
||||
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<MatrixRoomInfo> => {
|
||||
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<string> => {
|
||||
const cacheKey = `${roomId}:${userId}`;
|
||||
const cached = memberDisplayNameCache.get(cacheKey);
|
||||
|
||||
Reference in New Issue
Block a user