-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BE] feat#205 실제 퀴즈셋 가져오기 #213
Changes from all commits
bb03958
6adce76
fec3f3c
58ae029
b2d1c78
ddcdca6
30fc872
1fe3157
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { QuizSetData } from '../../InitDB/InitDB.Service'; | ||
import { Injectable, Logger } from '@nestjs/common'; | ||
import { InjectRedis } from '@nestjs-modules/ioredis'; | ||
import { Redis } from 'ioredis'; | ||
import { QuizService } from '../../quiz/quiz.service'; | ||
import { mockQuizData } from '../../../test/mocks/quiz-data.mock'; | ||
import { REDIS_KEY } from '../../common/constants/redis-key.constant'; | ||
|
||
@Injectable() | ||
export class QuizCacheService { | ||
Comment on lines
+9
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재는 아래처럼 각 방마다 퀴즈에 대한 정보가 저장되고 있습니다. 즉, 하나의 퀴즈셋이 메모리에 중복해서 저장될 수 있습니다.
만약 캐시를 본격적으로 도입한다면 아래 정보는 삭제하는 방향으로 가고, 퀴즈 진행 로직 관련해서 캐시된 데이터를 활용하는 걸로 수정해야 메모리를 효율적으로 쓸 수 있을 것 같습니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
private readonly quizCache = new Map<string, any>(); | ||
private readonly logger = new Logger(QuizCacheService.name); | ||
private readonly CACHE_TTL = 1000 * 60 * 30; // 30분 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 캐시 만료를 30분으로 잡아주신 이유가 있을까요? (궁금) |
||
|
||
constructor( | ||
@InjectRedis() private readonly redis: Redis, | ||
private readonly quizService: QuizService | ||
) {} | ||
|
||
/** | ||
* Redis 캐시에서 퀴즈셋 조회 | ||
*/ | ||
private async getFromRedisCache(quizSetId: number) { | ||
const cacheKey = REDIS_KEY.QUIZSET_ID(quizSetId); | ||
const cachedData = await this.redis.get(cacheKey); | ||
|
||
if (cachedData) { | ||
return JSON.parse(cachedData); | ||
} | ||
return null; | ||
} | ||
|
||
/** | ||
* Redis 캐시에 퀴즈셋 저장 | ||
*/ | ||
private async setToRedisCache(quizSetId: number, data: QuizSetData): Promise<void> { | ||
const cacheKey = REDIS_KEY.QUIZSET_ID(quizSetId); | ||
await this.redis.set(cacheKey, JSON.stringify(data), 'EX', this.CACHE_TTL); | ||
} | ||
|
||
/** | ||
* 퀴즈셋 데이터 조회 (캐시 활용) | ||
*/ | ||
async getQuizSet(quizSetId: number) { | ||
// 1. 로컬 메모리 캐시 확인 | ||
// const localCached = this.quizCache.get(this.getCacheKey(quizSetId)); | ||
// if (localCached) { | ||
// this.logger.debug(`Quiz ${quizSetId} found in local cache`); | ||
// return localCached; | ||
// } | ||
Comment on lines
+45
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거는 주석처리해두신 이유가 뭘까요? |
||
|
||
// 2. Redis 캐시 확인 | ||
const redisCached = await this.getFromRedisCache(quizSetId); | ||
if (redisCached) { | ||
this.logger.debug(`Quiz ${quizSetId} found in Redis cache`); | ||
// 로컬 캐시에도 저장 | ||
// this.quizCache.set(REDIS_KEY.QUIZSET_ID(quizSetId), redisCached); | ||
return redisCached; | ||
} | ||
|
||
// 3. DB에서 조회 | ||
const quizData = quizSetId === -1 ? mockQuizData : await this.quizService.findOne(quizSetId); | ||
|
||
// 4. 캐시에 저장 | ||
await this.setToRedisCache(quizSetId, quizData); | ||
this.quizCache.set(REDIS_KEY.QUIZSET_ID(quizSetId), quizData); | ||
|
||
return quizData; | ||
} | ||
|
||
/** | ||
* 캐시 무효화 | ||
*/ | ||
async invalidateCache(quizSetId: number): Promise<void> { | ||
const cacheKey = REDIS_KEY.QUIZSET_ID(quizSetId); | ||
this.quizCache.delete(cacheKey); | ||
await this.redis.del(cacheKey); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: 디폴트 퀴즈셋 -1을 게임방 만들 때부터 설정해두는 건 어떨까요? 그러면 아래의 경우에 quizSetTitle을 넣을 수 있게 됩니다.
그래서 이렇게 게임이 시작되기 전에 quizSetTitle 관리를 해줘야 대기방 목록 조회할 때 퀴즈셋 제목까지 정확히 보여줄 수 있습니다!