Skip to content
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

✨ [Feature/vote] implement save vote API #79

Merged
merged 40 commits into from
Mar 29, 2025
Merged

Conversation

linirini
Copy link
Member

@linirini linirini commented Mar 25, 2025

#️⃣ 연관된 이슈

📝 작업 내용

이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지 첨부 가능)

  • 사용자가 찬성 투표한 후보지 목록을 requestBody로 받아서 저장합니다.
  • 요청에 포함되지 않은 후보지는 반대로 판단합니다.
  • 재투표 시 기존 투표 정보를 제거한 후, 새로운 투표 정보를 저장합니다.

설계

결과 조회/갱신(재투표) 시 연산 최적화를 위해 2가지 방식으로 투표 정보를 관리합니다.

후보지 기준 구조 (찬성/반대 모두 관리)

room:{roomId}:candidate:{stationId}:agree → Set[memberId]
room:{roomId}:candidate:{stationId}:disagree → Set[memberId]

사용자 기준 구조 (사용자별 후보지 투표 상태 관리)

room:{roomId}:member:{memberId} → Hash[stationId: "agree"/"disagree"]

이에 따른 투표 결과 저장 로직

  1. 사용자 투표 내역이 존재한다면
    i) 사용자 기존 투표 내역 조회 -> HGETALL room:{roomId}:member:{memberId}
    ii) 조회한 데이터 기반으로 후보지에서 사용자 ID 제거 -> SREM room:{roomId}:candidate:{stationId}:{agree/disagree} {memberId}
    iii) 사용자 기존 투표 내역 정보 삭제 -> DEL room:{roomId}:member:{memberId}
  2. 사용자 투표 내역 저장
    i) 사용자 투표 내역 저장 -> HSET room:{roomId}:member:{memberId} {stationId} {agree/disagree}
    ii) 투표 결과에 따라 후보지에 사용자 ID 추가 -> SREM room:{roomId}:candidate:{stationId}:{agree/disagree} {memberId}

📸 스크린샷 (선택)

💬 리뷰 요구사항(선택)

  • 이전 작업 내용이 필요하여 해당 pr의 작업 내용만 모아 보시려면 링크를 눌러주세요!

yunyoung1819 and others added 28 commits February 11, 2025 23:42
⚙️ [chore/develop] update .gitignore file
@linirini linirini added ✨ Feature new feature 🥇 Urgency 1 긴급도 높음 labels Mar 25, 2025
@linirini linirini added this to the 2차 MVP milestone Mar 25, 2025
@linirini linirini self-assigned this Mar 25, 2025
@linirini linirini linked an issue Mar 25, 2025 that may be closed by this pull request
2 tasks
@linirini linirini changed the title ✨ [Feature/Vote] implement save vote API ✨ [Feature/vote] implement save vote API Mar 25, 2025
@RequestBody VoteRequest voteRequest
) {
voteFacadeService.createVote(roomId, memberId, voteRequest);
return ResponseEntity.ok(ApiResponseDto.success(null));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

응답값이 200인 경우만 처리되고 있는데 404, 500 등에 대한 반환값 처리도 구현되면 좀더 안전한 코드가 될 것 같습니다.

@Override
public void deleteAllByRoomIdAndMemberId(String roomId, String memberId) {
String key = getMemberVoteKey(roomId, memberId);
redisTemplate.delete(key);
Copy link
Collaborator

@yunyoung1819 yunyoung1819 Mar 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redis에 save, delete 등으로 데이터 변경 작업을 처리하고 있는데 DB에서처럼
trasaction이 걸려있고 실패 시에 Rollback 처리가 되지 않기 때문에 예외 처리 로직이 추가된다면
좀더 안전한 코드가 될 것 같아요. 삭제할때 redis 장애가 발생한 상태 또는 key가 만료된 상태 등. 여러가지 이유로 인해 삭제가 실패하는 경우에 대해 retry 또는 로그를 출력한다던가 등의 로직이 추가되면 좋을 것 같아요 😄

Copy link
Member Author

@linirini linirini Mar 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redis 오류에 의해 발생할 수 있는 에러를 파악하고, 각 에러에 따라 처리 방법에 대해 다음과 같이 정리해보았어요!

예외 종류 로그 레벨 클라이언트에 throw throw 시 예외 유형 클라이언트에 알리는 이유 retry 여부 retry 근거
RedisConnectionFailureException error Yes InternalServerError Redis 자체가 죽은 상태로, 정상 처리가 불가능 Yes 일시적 네트워크 장애, Redis 재시작 등의 가능성 있음
RedisSystemException error No (조회) / Yes (저장/삭제/수정) InternalServerError 저장 실패 시 데이터 불일치 우려. 수정/갱신 실패 시 데이터 오염 우려. 조회라면 fallback 가능하므로 무시 가능 No 직렬화 오류는 코드나 데이터 구조의 문제(개발자 잘못)이므로 반복해도 해결되지 않음
DataAccessException warn No - 대부분 명령어 수준의 오류로 fallback 처리 가능 No 일시적 오류거나 무시 가능 수준. 반복 시 큰 효과 없음
Exception (그 외 모든 예외) error Yes InternalServerError 알 수 없는 예외는 반드시 추적 및 알림 필요 No 원인 불명으로 재시도 전략 수립이 어려움

반복적인 try-catch에 대하여 탬플릿 메서드 패턴을 적용하여 RedisExecutor라는 util 클래스를 분리했어요!

예외 처리 커밋: 88dfe47

retry 커밋: 8ca1527

Copy link
Collaborator

@yunyoung1819 yunyoung1819 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리뷰가 늦어진 것 같아서 빠른 리뷰를 위해 새벽이지만 리뷰 남겨놓았습니다. 고생하셨어요 👍

@linirini linirini requested a review from yunyoung1819 March 29, 2025 07:06
Copy link
Collaborator

@yunyoung1819 yunyoung1819 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다! 작업한 부분이 많으셔서 고생 많이 하셨을 것 같아요 👍
우선 이렇게 머지하고, 다른 redis를 쓰는 곳에도 공통으로 적용되면 좋은 부분이라서 나중에 redisTemplate을 한번 감싸서 예외 처리 로직을 만들어두는 방식 등도 논의해보아도 좋을 것 같아요 😄

@linirini linirini merged commit 9c44744 into develop Mar 29, 2025
2 checks passed
@linirini linirini deleted the feature/save-vote branch March 29, 2025 07:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ Feature new feature 🥇 Urgency 1 긴급도 높음
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FEATURE] 투표하기 API
3 participants