diff --git a/README.md b/README.md index e90ff82..0f6f13f 100644 --- a/README.md +++ b/README.md @@ -8,18 +8,18 @@ - Node.js v20 - PNPM -- Docker +- Docker (dragonflydb - 3.5GB memory / 4 cores) ## Tech Stacks - Frontend - React.js, TailwindCSS, React-Query -- Backend - Express, socket.io, PostgreSQL, Redis +- Backend - Express, socket.io, PostgreSQL, DragonflyDB ## Get Started ### Run final build using docker compose -- Spin up the entire stack (Redis, PostgreSQL, React.js, Node.js) +- Spin up the entire stack (DragonflyDB, PostgreSQL, React.js, Node.js) ```bash pnpm docker:up ``` @@ -41,12 +41,12 @@ pnpm docker:down ### Development -- Spin up PostgreSQL and Redis +- Spin up PostgreSQL and DragonflyDB ```bash docker compose up -d ``` -> Make sure the ports (postgres: 5432, redis: 6379) are open for connection +> Make sure the ports (postgres: 5432, dragonfly: 6379) are open for connection - Install dependencies ```bash @@ -105,7 +105,7 @@ pnpm --filter web test - [x] realtime messaging - [x] typing indicators - [x] socket.io cluster adapter integration -- [x] redis implementation (typing users, online users) +- [x] dragonflydb implementation (typing users, online users) - [x] member online status - [x] realtime member list update - [x] infinite scroll cursor pagination (messages/groups/members) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 9cbf460..4ac4162 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -15,11 +15,14 @@ services: timeout: 10s retries: 5 - redis: - image: redis:7.2-alpine - restart: always + dragonfly: + image: 'docker.dragonflydb.io/dragonflydb/dragonfly' + restart: unless-stopped + command: dragonfly --proactor_threads=4 ports: - - '6379:6379' + - 6379:6379 + ulimits: + memlock: -1 healthcheck: test: ['CMD', 'redis-cli', 'ping'] interval: 30s diff --git a/docker-compose.yml b/docker-compose.yml index ccca414..c70475d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,8 +9,11 @@ services: environment: POSTGRES_PASSWORD: secret POSTGRES_DB: mchat - redis: - image: redis:7.2-alpine - restart: always + dragonfly: + image: 'docker.dragonflydb.io/dragonflydb/dragonfly' + restart: unless-stopped + command: dragonfly --proactor_threads=4 ports: - 6379:6379 + ulimits: + memlock: -1 diff --git a/server/.env.docker b/server/.env.docker index 61f833b..5a2eb6a 100644 --- a/server/.env.docker +++ b/server/.env.docker @@ -1,6 +1,6 @@ PORT=5000 JWT_SECRET=1009830912idhsjhdjfhiuh29hef98h1f8hf28hf98hef98h2f98fshdfhkjhajh CORS_ORIGIN=http://localhost:3000 -REDIS_HOST=redis +REDIS_HOST=dragonfly REDIS_PORT=6379 DB_URL="postgresql://postgres:secret@db:5432/mchat" diff --git a/server/src/modules/members/members.controller.ts b/server/src/modules/members/members.controller.ts index c8a8bc9..b471d3c 100644 --- a/server/src/modules/members/members.controller.ts +++ b/server/src/modules/members/members.controller.ts @@ -88,10 +88,11 @@ export const getGroupMembers: RequestHandler = async (req, res, next) => { const userIds = result.data.map(member => member.userId) const onlineMembers = await checkOnlineUsers(userIds) + console.log('online_members', onlineMembers) const membersWithOnlineStatus = result.data.map((member, index) => ({ ...member, - online: onlineMembers[index] === 1, + online: onlineMembers[index] == 1, })) res.json({ data: membersWithOnlineStatus, cursor: result.cursor }) diff --git a/server/src/redis/handlers.ts b/server/src/redis/handlers.ts index 484bc53..c87d1f6 100644 --- a/server/src/redis/handlers.ts +++ b/server/src/redis/handlers.ts @@ -65,6 +65,8 @@ export const markUserOffline = (userId: number) => { } export const checkOnlineUsers = async (userIds: number[]) => { + // redis: array of 1, 0 + // dragonfly: array of '1', '0' return redisClient.smismember(redisKeys.ONLINE_USERS, userIds) } diff --git a/server/src/redis/index.ts b/server/src/redis/index.ts index a27d95d..73c90d5 100644 --- a/server/src/redis/index.ts +++ b/server/src/redis/index.ts @@ -12,11 +12,11 @@ export function getRedisClient() { }) redisClient.on('connect', () => { - console.log('Redis connected'.yellow.bold) + console.log('DragonflyDB connected'.yellow.bold) }) redisClient.on('error', (...args) => { - console.log('Redis error: '.red.bold, ...args) + console.log('DragonflyDB error: '.red.bold, ...args) }) }