mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-02 10:01:34 +00:00
refactor(matrix): share bounded cache insertion (#113636)
This commit is contained in:
12
extensions/matrix/src/matrix/monitor/bounded-cache.ts
Normal file
12
extensions/matrix/src/matrix/monitor/bounded-cache.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
// Matrix plugin module implements bounded in-memory cache insertion.
|
||||
export function setBoundedMap<K, V>(map: Map<K, V>, key: K, value: V, maxEntries: number): void {
|
||||
map.set(key, value);
|
||||
if (map.size <= maxEntries) {
|
||||
return;
|
||||
}
|
||||
// Map insertion order keeps eviction FIFO without moving refreshed keys.
|
||||
const oldest = map.keys().next();
|
||||
if (!oldest.done) {
|
||||
map.delete(oldest.value);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
readJoinedMatrixMembers,
|
||||
} from "../direct-room.js";
|
||||
import type { MatrixClient } from "../sdk.js";
|
||||
import { setBoundedMap } from "./bounded-cache.js";
|
||||
|
||||
type DirectMessageCheck = {
|
||||
roomId: string;
|
||||
@@ -25,23 +26,8 @@ type DirectRoomTrackerOptions = {
|
||||
|
||||
const DM_CACHE_TTL_MS = 30_000;
|
||||
const RECENT_INVITE_TTL_MS = 30_000;
|
||||
const MAX_TRACKED_DM_ROOMS = 1024;
|
||||
const MAX_TRACKED_DM_MEMBER_FLAGS = 2048;
|
||||
|
||||
function rememberBounded<T>(
|
||||
map: Map<string, T>,
|
||||
key: string,
|
||||
value: T,
|
||||
maxSize = MAX_TRACKED_DM_ROOMS,
|
||||
): void {
|
||||
map.set(key, value);
|
||||
if (map.size > maxSize) {
|
||||
const oldest = map.keys().next().value;
|
||||
if (typeof oldest === "string") {
|
||||
map.delete(oldest);
|
||||
}
|
||||
}
|
||||
}
|
||||
const MAX_DM_ROOMS = 1024;
|
||||
const MAX_DM_MEMBER_FLAGS = 2048;
|
||||
|
||||
export function createDirectRoomTracker(client: MatrixClient, opts: DirectRoomTrackerOptions = {}) {
|
||||
const log = opts.log ?? (() => {});
|
||||
@@ -87,7 +73,7 @@ export function createDirectRoomTracker(client: MatrixClient, opts: DirectRoomTr
|
||||
if (!normalized) {
|
||||
throw new Error("membership unavailable");
|
||||
}
|
||||
rememberBounded(joinedMembersCache, roomId, { members: normalized, ts: now });
|
||||
setBoundedMap(joinedMembersCache, roomId, { members: normalized, ts: now }, MAX_DM_ROOMS);
|
||||
return normalized;
|
||||
} catch (err) {
|
||||
log(`matrix: dm member lookup failed room=${roomId} (${String(err)})`);
|
||||
@@ -110,12 +96,7 @@ export function createDirectRoomTracker(client: MatrixClient, opts: DirectRoomTr
|
||||
return cached.isDirect;
|
||||
}
|
||||
const isDirect = await hasDirectMatrixMemberFlag(client, roomId, normalizedUserId);
|
||||
rememberBounded(
|
||||
directMemberFlagCache,
|
||||
cacheKey,
|
||||
{ isDirect, ts: now },
|
||||
MAX_TRACKED_DM_MEMBER_FLAGS,
|
||||
);
|
||||
setBoundedMap(directMemberFlagCache, cacheKey, { isDirect, ts: now }, MAX_DM_MEMBER_FLAGS);
|
||||
return isDirect;
|
||||
};
|
||||
|
||||
@@ -186,9 +167,12 @@ export function createDirectRoomTracker(client: MatrixClient, opts: DirectRoomTr
|
||||
if (!normalizedRemoteUserId) {
|
||||
return;
|
||||
}
|
||||
rememberBounded(locallyPromotedDirectRooms, roomId, {
|
||||
remoteUserId: normalizedRemoteUserId,
|
||||
});
|
||||
setBoundedMap(
|
||||
locallyPromotedDirectRooms,
|
||||
roomId,
|
||||
{ remoteUserId: normalizedRemoteUserId },
|
||||
MAX_DM_ROOMS,
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -207,10 +191,8 @@ export function createDirectRoomTracker(client: MatrixClient, opts: DirectRoomTr
|
||||
if (!normalizedRemoteUserId) {
|
||||
return;
|
||||
}
|
||||
rememberBounded(recentInviteCandidates, roomId, {
|
||||
remoteUserId: normalizedRemoteUserId,
|
||||
ts: Date.now(),
|
||||
});
|
||||
const invite = { remoteUserId: normalizedRemoteUserId, ts: Date.now() };
|
||||
setBoundedMap(recentInviteCandidates, roomId, invite, MAX_DM_ROOMS);
|
||||
log(`matrix: remembered invite candidate room=${roomId} sender=${normalizedRemoteUserId}`);
|
||||
},
|
||||
isDirectMessage: async (params: DirectMessageCheck): Promise<boolean> => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Matrix plugin module implements room info behavior.
|
||||
import { isMatrixNotFoundError } from "../errors.js";
|
||||
import type { MatrixClient } from "../sdk.js";
|
||||
import { setBoundedMap } from "./bounded-cache.js";
|
||||
|
||||
export type MatrixRoomInfo = {
|
||||
name?: string;
|
||||
@@ -10,18 +11,8 @@ export type MatrixRoomInfo = {
|
||||
aliasesResolved: boolean;
|
||||
};
|
||||
|
||||
const MAX_TRACKED_ROOM_INFO = 1024;
|
||||
const MAX_TRACKED_MEMBER_DISPLAY_NAMES = 4096;
|
||||
|
||||
function rememberBounded<T>(map: Map<string, T>, key: string, value: T, maxEntries: number): void {
|
||||
map.set(key, value);
|
||||
if (map.size > maxEntries) {
|
||||
const oldest = map.keys().next().value;
|
||||
if (typeof oldest === "string") {
|
||||
map.delete(oldest);
|
||||
}
|
||||
}
|
||||
}
|
||||
const MAX_ROOM_INFO = 1024;
|
||||
const MAX_MEMBER_DISPLAY_NAMES = 4096;
|
||||
|
||||
export function createMatrixRoomInfoResolver(client: MatrixClient) {
|
||||
const roomNameCache = new Map<string, Pick<MatrixRoomInfo, "name" | "nameResolved">>();
|
||||
@@ -52,7 +43,7 @@ export function createMatrixRoomInfoResolver(client: MatrixClient) {
|
||||
}
|
||||
const info = { name, nameResolved };
|
||||
if (nameResolved) {
|
||||
rememberBounded(roomNameCache, roomId, info, MAX_TRACKED_ROOM_INFO);
|
||||
setBoundedMap(roomNameCache, roomId, info, MAX_ROOM_INFO);
|
||||
}
|
||||
return info;
|
||||
};
|
||||
@@ -84,7 +75,7 @@ export function createMatrixRoomInfoResolver(client: MatrixClient) {
|
||||
}
|
||||
const info = { canonicalAlias, altAliases, aliasesResolved };
|
||||
if (aliasesResolved) {
|
||||
rememberBounded(roomAliasCache, roomId, info, MAX_TRACKED_ROOM_INFO);
|
||||
setBoundedMap(roomAliasCache, roomId, info, MAX_ROOM_INFO);
|
||||
}
|
||||
return info;
|
||||
};
|
||||
@@ -111,12 +102,7 @@ export function createMatrixRoomInfoResolver(client: MatrixClient) {
|
||||
.catch(() => null);
|
||||
const displayName =
|
||||
memberState && typeof memberState.displayname === "string" ? memberState.displayname : userId;
|
||||
rememberBounded(
|
||||
memberDisplayNameCache,
|
||||
cacheKey,
|
||||
displayName,
|
||||
MAX_TRACKED_MEMBER_DISPLAY_NAMES,
|
||||
);
|
||||
setBoundedMap(memberDisplayNameCache, cacheKey, displayName, MAX_MEMBER_DISPLAY_NAMES);
|
||||
return displayName;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user