Skip to content

Commit e84f7da

Browse files
authored
feat: Implement redis adapter for chat-service (#74)
Description --- This pull request primarily introduces the redis adapter to the chat service and making adaptations to accommodate for horizontal scaling of the service. Additionally introduces bug fixes to the chat service to function in-line with the collab service behavior.
1 parent 82b0f45 commit e84f7da

File tree

8 files changed

+379
-89
lines changed

8 files changed

+379
-89
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
PORT=5286
2+
REDIS_URL=redis://redis:6379

backend-services/chatting-backend-service/package-lock.json

Lines changed: 136 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend-services/chatting-backend-service/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
"lint": "eslint ."
1515
},
1616
"dependencies": {
17+
"@socket.io/redis-adapter": "^8.3.0",
1718
"cors": "^2.8.5",
1819
"dotenv": "^17.2.3",
1920
"express": "^5.1.0",
2021
"mongoose": "^8.19.1",
22+
"redis": "^5.9.0",
2123
"socket.io": "^4.8.1"
2224
},
2325
"devDependencies": {
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { createClient } from "redis";
2+
3+
class RedisService {
4+
static instance = null;
5+
6+
constructor() {
7+
const redisUrl = process.env.REDIS_URL || "redis://localhost:6379";
8+
9+
this.pubClient = createClient({ url: redisUrl });
10+
this.subClient = this.pubClient.duplicate();
11+
this.appClient = this.pubClient.duplicate();
12+
13+
const handleError = (label) => (err) =>
14+
console.error(`Redis ${label} Error:`, err);
15+
16+
this.pubClient.on("error", handleError("Pub"));
17+
this.subClient.on("error", handleError("Sub"));
18+
this.appClient.on("error", handleError("App"));
19+
}
20+
21+
async connect() {
22+
await Promise.all([
23+
this.pubClient.connect(),
24+
this.subClient.connect(),
25+
this.appClient.connect(),
26+
]);
27+
console.log("Redis connected");
28+
}
29+
30+
static async getInstance() {
31+
if (!RedisService.instance) {
32+
const service = new RedisService();
33+
await service.connect();
34+
RedisService.instance = service;
35+
}
36+
return RedisService.instance;
37+
}
38+
39+
// -------- Room operations --------
40+
async addOrUpdateUser(roomId, userId, data) {
41+
await this.appClient.hSet(
42+
`room:${roomId}:users`,
43+
userId,
44+
JSON.stringify(data),
45+
);
46+
}
47+
48+
async getUser(roomId, userId) {
49+
const raw = await this.appClient.hGet(`room:${roomId}:users`, userId);
50+
return raw ? JSON.parse(raw) : null;
51+
}
52+
53+
async getAllUsers(roomId) {
54+
const users = await this.appClient.hGetAll(`room:${roomId}:users`);
55+
return Object.fromEntries(
56+
Object.entries(users).map(([id, val]) => [id, JSON.parse(val)]),
57+
);
58+
}
59+
60+
async removeUser(roomId, userId) {
61+
await this.appClient.hDel(`room:${roomId}:users`, userId);
62+
}
63+
64+
async deleteRoom(roomId) {
65+
await this.appClient.del(`room:${roomId}:users`);
66+
}
67+
}
68+
69+
export default RedisService;

0 commit comments

Comments
 (0)