Skip to content

Commit 2d24686

Browse files
committed
refactor: Enhance user caching mechanism for publication access with timeout management
1 parent a3db465 commit 2d24686

1 file changed

Lines changed: 18 additions & 18 deletions

File tree

apps/meteor/server/modules/streamer/publication-user-cache.ts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,37 @@ import { Users } from '@rocket.chat/models';
44
import type { IPublication } from './types';
55

66
const CACHE_PROJECTION = { _id: 1, roles: 1 } as const;
7+
const CACHE_TIMEOUT = 1000 * 60;
8+
const cacheByPublication = new Map<string, { user: Pick<IUser, '_id' | 'roles'>; timeout: NodeJS.Timeout }>();
79

8-
/** Cache keyed by publication so entries can be GC'd when the subscription is gone. */
9-
const cacheByPublication = new WeakMap<IPublication, { user: IUser | null; userId: string }>();
10-
11-
/** User ids that received watch.users; next get for a publication with that userId will refetch. */
12-
const invalidatedUserIds = new Set<string>();
13-
14-
export async function getCachedUserForPublication(publication: IPublication): Promise<IUser | null> {
10+
export async function getCachedUserForPublication(publication: IPublication): Promise<Pick<IUser, '_id' | 'roles'> | null> {
1511
const userId = publication.userId ?? publication._session?.userId ?? undefined;
1612
if (userId == null || userId === '') {
1713
return null;
1814
}
1915

20-
const entry = cacheByPublication.get(publication);
16+
const entry = cacheByPublication.get(userId);
17+
2118
if (entry) {
22-
if (invalidatedUserIds.has(entry.userId)) {
23-
const user = await Users.findOneById(entry.userId, { projection: CACHE_PROJECTION });
24-
const value = user ?? null;
25-
cacheByPublication.set(publication, { user: value, userId: entry.userId });
26-
invalidatedUserIds.delete(entry.userId);
27-
return value;
28-
}
19+
clearTimeout(entry.timeout);
20+
entry.timeout = setTimeout(() => {
21+
cacheByPublication.delete(userId);
22+
}, CACHE_TIMEOUT);
2923
return entry.user;
3024
}
3125

32-
const user = await Users.findOneById(userId, { projection: CACHE_PROJECTION });
26+
const user = await Users.findOneById<Pick<IUser, '_id' | 'roles'>>(userId, { projection: CACHE_PROJECTION });
3327
const value = user ?? null;
34-
cacheByPublication.set(publication, { user: value, userId });
28+
if (value) {
29+
const timeout = setTimeout(() => {
30+
cacheByPublication.delete(userId);
31+
}, CACHE_TIMEOUT);
32+
33+
cacheByPublication.set(userId, { user: value, timeout });
34+
}
3535
return value;
3636
}
3737

3838
export function invalidate(userId: string): void {
39-
invalidatedUserIds.add(userId);
39+
cacheByPublication.delete(userId);
4040
}

0 commit comments

Comments
 (0)