feat(be): implement participant presence in study rooms#3541
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements a real-time study room feature using NestJS WebSockets, Redis, and BullMQ for session management. It introduces a StudyRoomService, a StudyGateway, and a global RedisModule. Feedback highlights a critical issue where modifying socket data via fetchSockets() fails to persist across clustered nodes, and identifies a bug where a code property is missing from join validation results. Further improvements are suggested to make the Redis database index configurable, remove the redundant redis dependency, and provide specific error codes for consistent client-side handling.
| useFactory: async (config: ConfigService) => { | ||
| const host = config.get<string>('REDIS_HOST') | ||
| const port = config.get<number>('REDIS_PORT') | ||
| const db = 1 |
There was a problem hiding this comment.
이것도 뭐임! app.module.ts도 확인부탁
There was a problem hiding this comment.
admin 단에서 사용하던 Redis 설정을 그대로 가져온 코드였어서 확인해보니
이전에 BullMQ와 Cache 간 Redis DB 충돌로 장애가 발생해서 (#3069) DB를 분리한 이력이 있는데, 해당 설정을 그대로 차용했습니다.
현재 서비스 상 Redis DB 구조는 다음과 같은데
db 0 → CacheModule
db 1 → BullMQ (client: prefix 'bull-client', admin: prefix 'bull')
db 1 → RedisModule (웹소켓 어댑터, 스터디룸 기능)
BullMQ는 client/admin 각각 prefix로 키를 구분하고 있어서 같은 db 1을 사용해도 충돌은 없을 것 같습니다. (근데 분리하는 것이 좋을 것 같기도 합니다.)
또한 RedisModule(웹소켓 어댑터 + 스터디룸)은 prefix 없이 db 1을 그대로 사용하고 있어서 다른 db로 분리하는 게 안전할 것 같은데, 이 부분은 제가 임의로 결정하기보다 같이 논의하고 싶은데 어떻게 생각하시나요?
| "pino-http": "^10.5.0", | ||
| "pino-pretty": "^11.3.0", | ||
| "prisma-graphql-type-decimal": "^3.0.1", | ||
| "redis": "^5.11.0", |
Description
Study Room(Study Group 2depth)에서 사용자의 실시간 출입 상태 처리 기능을 구현합니다.
WebSocket(Socket.IO) + Redis + BullMQ 기반으로 입장/퇴장/재연결/세션 종료를 처리합니다.
Additional context
인프라 설정
@libs/redis: Redis 모듈 및RedisIoAdapter추가main.ts:RedisIoAdapter등록 (멀티 서버 환경 대응)JwtAuthGuard: WebSocket 컨텍스트에서handshake.auth.token으로 JWT 인증 처리study.module.ts:StudyGateway,StudyRoomService,StudyRoomProcessor등록구현
입장 (
room:join)SET NX로 race condition 방지 — 동시 입장 시 단 한 명만 첫 번째 입장자로 처리2시간 고정-> DB에서 endTime 가져오는 것으로 수정퇴장
room:leave): ack 응답으로 처리, 잔류 인원에게room:participantsChangedemithandleDisconnect): 30초 유예 후 완전 퇴장 처리reconnectKeyDEL 반환값으로 원자적 복구 판단 (TOCTOU 방지)세션 종료 (BullMQ)
room:reminderemitroom:endedemit → 소켓 강제 퇴장 → Redis 초기화room-end:{groupId})으로 중복 job 방지이벤트 목록
room:joinroom:leaveroom:startedroom:participantsChangedroom:participantReconnectingroom:participantReconnectedroom:reminderroom:endedBefore submitting the PR, please make sure you do the following
fixes #123).