Skip to content

Commit cba3ae4

Browse files
committed
Use redis sets instead of json arrays
1 parent 75a0f9c commit cba3ae4

3 files changed

Lines changed: 55 additions & 13 deletions

File tree

packages/server/api/src/app/ai/chat/ai-chat.service.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,7 @@ export const createChatContext = async (
141141
chatExpireTime,
142142
);
143143
const indexKey = userChatsIndexKey(userId, projectId);
144-
const existing =
145-
(await cacheWrapper.getSerializedObject<string[]>(indexKey)) ?? [];
146-
147-
if (!existing.includes(chatId)) {
148-
existing.push(chatId);
149-
await cacheWrapper.setSerializedObject(indexKey, existing, chatExpireTime);
150-
}
144+
await cacheWrapper.addToSet(indexKey, chatId, chatExpireTime);
151145
};
152146

153147
export const getChatContext = async (
@@ -189,8 +183,7 @@ export const getAllChats = async (
189183
projectId: string,
190184
): Promise<{ chatId: string; chatName: string }[]> => {
191185
const indexKey = userChatsIndexKey(userId, projectId);
192-
const chatIds =
193-
(await cacheWrapper.getSerializedObject<string[]>(indexKey)) ?? [];
186+
const chatIds = await cacheWrapper.getSetMembers(indexKey);
194187

195188
if (chatIds.length === 0) {
196189
return [];
@@ -239,14 +232,12 @@ export const deleteChatHistory = async (
239232
projectId: string,
240233
): Promise<void> => {
241234
const indexKey = userChatsIndexKey(userId, projectId);
242-
const [chatIds] = await Promise.all([
243-
cacheWrapper.getSerializedObject<string[]>(indexKey),
235+
await Promise.all([
244236
cacheWrapper.deleteKey(chatHistoryKey(chatId, userId, projectId)),
245237
cacheWrapper.deleteKey(chatToolsKey(chatId, userId, projectId)),
246238
cacheWrapper.deleteKey(chatContextKey(chatId, userId, projectId)),
239+
cacheWrapper.removeFromSet(indexKey, chatId),
247240
]);
248-
const updatedIds = (chatIds ?? []).filter((id) => id !== chatId);
249-
await cacheWrapper.setSerializedObject(indexKey, updatedIds);
250241
};
251242

252243
/**

packages/server/shared/src/lib/cache/memory-wrapper.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,28 @@ const getBufferAndDelete = async (key: string): Promise<Buffer | null> => {
7373
throw new Error('Not implemented');
7474
};
7575

76+
const addToSet = async (
77+
key: string,
78+
member: string,
79+
expireInSeconds: number = DEFAULT_EXPIRE_TIME / 1000,
80+
): Promise<void> => {
81+
const existing = (await getSerializedObject<string[]>(key)) ?? [];
82+
if (!existing.includes(member)) {
83+
existing.push(member);
84+
}
85+
await setSerializedObject(key, existing, expireInSeconds);
86+
};
87+
88+
const removeFromSet = async (key: string, member: string): Promise<void> => {
89+
const existing = (await getSerializedObject<string[]>(key)) ?? [];
90+
const updated = existing.filter((id) => id !== member);
91+
await setSerializedObject(key, updated);
92+
};
93+
94+
const getSetMembers = async (key: string): Promise<string[]> => {
95+
return (await getSerializedObject<string[]>(key)) ?? [];
96+
};
97+
7698
export const memoryWrapper = {
7799
setKey,
78100
getKey,
@@ -84,4 +106,7 @@ export const memoryWrapper = {
84106
setSerializedObject,
85107
getSerializedObject,
86108
scanKeys,
109+
addToSet,
110+
removeFromSet,
111+
getSetMembers,
87112
};

packages/server/shared/src/lib/cache/redis-wrapper.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,29 @@ async function setSerializedObject<T>(
5959
await setKey(key, JSON.stringify(obj), expireInSeconds);
6060
}
6161

62+
const addToSet = async (
63+
key: string,
64+
member: string,
65+
expireInSeconds?: number,
66+
): Promise<void> => {
67+
const redis = getRedisClient();
68+
await redis.sadd(key, member);
69+
70+
if (expireInSeconds && expireInSeconds > 0) {
71+
await redis.expire(key, expireInSeconds);
72+
}
73+
};
74+
75+
const removeFromSet = async (key: string, member: string): Promise<void> => {
76+
const redis = getRedisClient();
77+
await redis.srem(key, member);
78+
};
79+
80+
const getSetMembers = async (key: string): Promise<string[]> => {
81+
const redis = getRedisClient();
82+
return redis.smembers(key);
83+
};
84+
6285
// eslint-disable-next-line @typescript-eslint/no-explicit-any
6386
async function getOrAdd<T, Args extends any[]>(
6487
key: string,
@@ -134,4 +157,7 @@ export const redisWrapper = {
134157
setSerializedObject,
135158
getSerializedObject,
136159
scanKeys,
160+
addToSet,
161+
removeFromSet,
162+
getSetMembers,
137163
};

0 commit comments

Comments
 (0)