-
Notifications
You must be signed in to change notification settings - Fork 1
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
feat : 예매대기 처리 스케줄러 구현 #43
Conversation
…dateToActiveById 쿼리 구현
…teSeatToAvailable 메소드 구현
…ctivateWaitingBooking 구현
🦞 Test Coverage Report
|
settings.gradle
Outdated
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.
스케줄러 모듈 설정 잘 추가하신 것 같아요! 👍🏻
@@ -52,6 +53,8 @@ public class WaitingBooking extends TimeBaseEntity { | |||
|
|||
private int seatCount; | |||
|
|||
private LocalDateTime expireAt; |
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.
expiredAt 은 어떤가요?! (근데 사실 너무 사소함 ㅎㅎ)
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.
의미적으로 그게 더 맞는거같네요! 수정하겠습니다 ㅎㅎ
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.
b84ab45
수정 했습니다~
@@ -108,4 +111,10 @@ public static WaitingBooking of( | |||
) { | |||
return new WaitingBooking(user, seatCount, seatIds); | |||
} | |||
|
|||
public List<Long> getSelectedSeatIds() { |
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.
예약 대기 좌석에 해당하는 좌석 id값을 list로 반환하는 함수가 맞을까요?
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.
네 맞습니다~ 👍
CANCELED("예매 취소"); | ||
CANCELED("예매 취소"), | ||
// 취소된 좌석이 예매대기로 인해 6시간동안 예매대기를 한 사용자에 한해 예약이 가능한 상태 | ||
WAITING("예매 대기"); |
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.
👍🏻👍🏻
SeatFixture.getSeat() | ||
); | ||
// 0번 Seat 만 Canceled 상태로 변경(취소 기능이 아직 구현되지 않아서 리플렉션 사용) | ||
ReflectionTestUtils.setField(seats.get(0), "seatStatus", SeatStatus.CANCELED); |
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.
👍🏻👍🏻
저도 배워갑니다
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.
리플랙션이 정말 사기적인 기술이긴한데.. 안좋은 측면도 있어서 남발하지만 않으면 좋은거같아요!
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.
테스트 꼼꼼히 잘 작성하셨어요!! 굿굿
@Override | ||
public List<WaitingBooking> findAll() { | ||
return waitingBookingJpaRepository.findAll(); | ||
} | ||
|
||
@Override | ||
public List<WaitingBooking> findByStatusIsWaiting() { | ||
return waitingBookingJpaRepository.findByStatusOrderByIdDesc(WaitingStatus.WAITING); |
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.
네이밍 굿굿 한번에 바로 파악했네요
} | ||
|
||
@Override | ||
public void updateToActiveById(Long id) { |
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.
updateStatusToActiveById 는 어떨까요?! (이것도 사소해~)
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.
이 쿼리가 어댑터쪽 코드보면 상태변경도있는데 expireAt 도 6시간 뒤로 설정해주는 쿼리라서 이렇게 네이밍했어요!
|
||
public interface WaitingBookingJpaRepository extends JpaRepository<WaitingBooking, Long> { | ||
|
||
@EntityGraph(attributePaths = {"user", "waitingBookingSeats"}) |
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.
이거 fetch join으로 한번에 다 가져오는게 맞나용??
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.
넵 맞아요 user 는 이메일 보낼때 사용될거같아서 넣었고 waitingBookingSeats 는 예약대기 처리하는 로직에서 사용돼서 같이 패칭했습니다
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.
아주 좋습니다👍🏻👍🏻
// 좌석을 대기중 상태로 변경 | ||
@Transactional | ||
public void updateSeatToWaiting(Collection<Long> targetIds) { | ||
seatRepository.updateStatusByIdIn(targetIds, SeatStatus.WAITING); |
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.
이거 뒤에 In 은 무슨의미인가요?!
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.
In 절을 통해 가져온다는 의미에요!
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.
최소 단위 기능으로 메서드로 분리한거 굿굿
// ID 에 해당하는 WaitingBooking ACTIVATION 상태로 변경하고 expireAt 6시간뒤로 설정 | ||
@Transactional | ||
public void activateWaitingBooking(Long waitingBookingId) { | ||
waitingBookingRepository.updateToActiveById(waitingBookingId); |
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.
이것도 updateStatusToActivateById 는 어떠신가요? ㅎㅎ (이거도 단순히 제안 ㅎㅎㅎ)
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.
의미상으로 "예약대기를 활성화한다" 라는 의미를 담은 서비스로직이라고 생각해서 제 생각에는 나은거같다고 생각이 듭니다! 수진님이 강력히 원하시는건 아닌거같으니...ㅎㅎ 이대로 가볼게요 ㅎㅎ
int seatCount | ||
) { | ||
List<Long> matchSeatIds = new ArrayList<>(); | ||
for (Long selectedSeatId : selectedSeatIds) { |
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.
이부분 stream으로 처리는 어려운건가용??
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.
그 바로 아랫줄에 사이즈가 seatCount 랑 같아지면 break 치는 부분이 있는데 stream forEach 에선 break 를 지원안해서 이렇게 구현했습니다~!
|
||
public WaitingRegisterResponse registerWaitingBooking(Long userId, WaitingRegisterRequest request) { | ||
User user = userService.getUserById(userId); | ||
WaitingBooking waitingBooking = waitingBookingService.createWaitingBooking(user, request); | ||
|
||
return new WaitingRegisterResponse(waitingBooking.getId()); | ||
} | ||
|
||
public void processWaitingBooking() { |
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.
주석으로 설명을 잘 해놓아서 어떤 흐름인지 이해가 잘 되네요 👍🏻👍🏻
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { | ||
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); | ||
|
||
scheduler.setPoolSize(10); |
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.
이거 사이즈를 10으로 설정하신 이유가 있나요?
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.
아 이건 특별한 이유 없습니다.
스레드 풀 사이즈 지정하는건 배포하면 거기에 맞춰서 설정해야될거같아서 일단 임의로 10 했습니다
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.
👍🏻
|
||
private final WaitingBookingFacade waitingBookingFacade; | ||
|
||
@Scheduled(cron = "0 */10 * * * *") |
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.
이게 10분마다 스케줄러가 작동하는게 맞나요?
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.
10분마다 돌아가게 설정한 부분입니다!
비즈니스적으로 몇분마다 돌릴지는 같이 상의해봐야겠네요 🤔
@RequiredArgsConstructor | ||
public class WaitingBookingScheduler { | ||
|
||
private final WaitingBookingFacade waitingBookingFacade; |
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.
👍🏻👍🏻 퍼사드 패턴을 잘 활용하시는 것 같아요
설계 너무 잘하셨네요
@Autowired | ||
private SeatRepository seatRepository; | ||
|
||
private void assertSeatStatus(Long id, SeatStatus expected) { |
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.
와 이거 검증로직 길어지면 이렇게 빼니 훨씬 가독성 좋네요
저도 이거 이용해봐야겠어요 ㅎㅎ
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.
예약대기 스케줄러 통합테스트 잘 짜신듯!!! 🤩 고생많으셨어요
전체적으로 설계도 꼼꼼하게 잘 하셨고, 잘 구현하신 것 같아요 |
🦞 Test Coverage Report
|
* chore : scheduler 모듈 설정 구성 * feat : 6시간 요구사항에 사용되는 expireAt 필드 추가 & getSelectedSeatIds 메소드 추가 * feat : User 엔티티에 테스트용 생성자 추가 * feat : SeatStatus 에 예매대기 상태 추가 * feat : SeatRepository - findById, findByStatusIsCanceled, updateStatusByIdIn 쿼리 구현 * feat : WaitingBookingRepository - findById, findByStatusIsWaiting, updateToActiveById 쿼리 구현 * feat : SeatFixture 데이터추가 * feat : WaitingBookingFixture 구현 * feat : SeatService 구현 & getCanceledSeatIds, updateSeatToWaiting, updateSeatToAvailable 메소드 구현 * feat : WaitingBookingService - getWaitingBookingsByStatusIsWaiting, activateWaitingBooking 구현 * feat : WaitingBookingFacade - 예약대기를 처리하는 processWaitingBooking 메소드 구현 * feat : 스케줄러 설정 및 스케줄러에 사용되는 스레드 설정 추가 * feat : 예약대기 스케줄러 구현 * refactor : expireAt 컬럼 expiredAt 으로 네이밍 변경
📄 무엇을 개발했나요?
🍸 무엇을 집중적으로 리뷰해야할까요?