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

feat : 예매대기 처리 스케줄러 구현 #43

Merged
merged 14 commits into from
Dec 28, 2023
Merged

feat : 예매대기 처리 스케줄러 구현 #43

merged 14 commits into from
Dec 28, 2023

Conversation

EunChanNam
Copy link
Member

📄 무엇을 개발했나요?

  • 스케줄러 모듈 정의
  • 예매대기 처리 스케줄러 구현

🍸 무엇을 집중적으로 리뷰해야할까요?

  • 파일체인지가 많아요..! 그래서 한 파일에 대한 수정은 한커밋에서만 이루어지게 해놨습니다. 커밋 보시면서 리뷰하시면 편하실거에요!

@EunChanNam EunChanNam added the ✏️ Feat 기능 개발 label Dec 27, 2023
@EunChanNam EunChanNam added this to the 2차 스프린트 milestone Dec 27, 2023
@EunChanNam EunChanNam self-assigned this Dec 27, 2023
Copy link

🦞 Test Coverage Report

Overall Project NaN% NaN% 🟢

There is no coverage information present for the Files changed

settings.gradle Outdated
Copy link
Contributor

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;
Copy link
Contributor

Choose a reason for hiding this comment

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

expiredAt 은 어떤가요?! (근데 사실 너무 사소함 ㅎㅎ)

Copy link
Member Author

Choose a reason for hiding this comment

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

의미적으로 그게 더 맞는거같네요! 수정하겠습니다 ㅎㅎ

Copy link
Member Author

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() {
Copy link
Contributor

Choose a reason for hiding this comment

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

예약 대기 좌석에 해당하는 좌석 id값을 list로 반환하는 함수가 맞을까요?

Copy link
Member Author

Choose a reason for hiding this comment

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

네 맞습니다~ 👍

CANCELED("예매 취소");
CANCELED("예매 취소"),
// 취소된 좌석이 예매대기로 인해 6시간동안 예매대기를 한 사용자에 한해 예약이 가능한 상태
WAITING("예매 대기");
Copy link
Contributor

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);
Copy link
Contributor

Choose a reason for hiding this comment

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

👍🏻👍🏻
저도 배워갑니다

Copy link
Member Author

Choose a reason for hiding this comment

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

리플랙션이 정말 사기적인 기술이긴한데.. 안좋은 측면도 있어서 남발하지만 않으면 좋은거같아요!

Copy link
Contributor

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);
Copy link
Contributor

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) {
Copy link
Contributor

Choose a reason for hiding this comment

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

updateStatusToActiveById 는 어떨까요?! (이것도 사소해~)

Copy link
Member Author

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"})
Copy link
Contributor

Choose a reason for hiding this comment

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

이거 fetch join으로 한번에 다 가져오는게 맞나용??

Copy link
Member Author

Choose a reason for hiding this comment

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

넵 맞아요 user 는 이메일 보낼때 사용될거같아서 넣었고 waitingBookingSeats 는 예약대기 처리하는 로직에서 사용돼서 같이 패칭했습니다

Copy link
Contributor

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);
Copy link
Contributor

Choose a reason for hiding this comment

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

이거 뒤에 In 은 무슨의미인가요?!

Copy link
Member Author

Choose a reason for hiding this comment

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

In 절을 통해 가져온다는 의미에요!

Copy link
Contributor

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);
Copy link
Contributor

Choose a reason for hiding this comment

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

이것도 updateStatusToActivateById 는 어떠신가요? ㅎㅎ (이거도 단순히 제안 ㅎㅎㅎ)

Copy link
Member Author

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) {
Copy link
Contributor

Choose a reason for hiding this comment

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

이부분 stream으로 처리는 어려운건가용??

Copy link
Member Author

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() {
Copy link
Contributor

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);
Copy link
Contributor

Choose a reason for hiding this comment

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

이거 사이즈를 10으로 설정하신 이유가 있나요?

Copy link
Member Author

Choose a reason for hiding this comment

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

아 이건 특별한 이유 없습니다.
스레드 풀 사이즈 지정하는건 배포하면 거기에 맞춰서 설정해야될거같아서 일단 임의로 10 했습니다

Copy link
Contributor

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 * * * *")
Copy link
Contributor

Choose a reason for hiding this comment

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

이게 10분마다 스케줄러가 작동하는게 맞나요?

Copy link
Member Author

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;
Copy link
Contributor

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) {
Copy link
Contributor

Choose a reason for hiding this comment

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

와 이거 검증로직 길어지면 이렇게 빼니 훨씬 가독성 좋네요
저도 이거 이용해봐야겠어요 ㅎㅎ

Copy link
Contributor

Choose a reason for hiding this comment

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

예약대기 스케줄러 통합테스트 잘 짜신듯!!! 🤩 고생많으셨어요

@ssssujini99
Copy link
Contributor

ssssujini99 commented Dec 28, 2023

전체적으로 설계도 꼼꼼하게 잘 하셨고, 잘 구현하신 것 같아요
수고하셨습니다 !!!!

Copy link

🦞 Test Coverage Report

Overall Project NaN% NaN% 🟢

There is no coverage information present for the Files changed

@EunChanNam EunChanNam merged commit f056544 into dev Dec 28, 2023
2 checks passed
@EunChanNam EunChanNam deleted the feat/#37 branch December 28, 2023 17:09
EunChanNam added a commit that referenced this pull request Jan 15, 2024
* 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 으로 네이밍 변경
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✏️ Feat 기능 개발
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants