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

πŸ”¨ Refactor/#185 - κ²Œμ‹œνŒμ— κΈ°κ°„ μΆ”κ°€, 기간에 λ”°λ₯Έ μŠ€μΌ€μ€„λ§ 둜직 μΆ”κ°€ 및 Response λ³€κ²½ #186

Merged
merged 1 commit into from
Dec 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/com/daon/onjung/account/domain/Store.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public class Store {
/* -------------------------------------------- */
/* One To One Mapping ------------------------ */
/* -------------------------------------------- */
@OneToOne
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "owner_id")
private Owner owner;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import com.daon.onjung.core.exception.type.CommonException;
import com.daon.onjung.event.repository.redis.ScheduledEventJobRepository;
import com.daon.onjung.event.application.controller.consumer.EventSchedulerConsumerV1Controller;
import com.daon.onjung.suggestion.application.controller.consumer.BoardSchedulerConsumerV1Controller;
import com.daon.onjung.suggestion.domain.redis.ScheduledBoardJob;
import com.daon.onjung.suggestion.repository.redis.ScheduledBoardJobRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
Expand All @@ -21,6 +24,7 @@ public class AppEventListener {
private final Scheduler scheduler;

private final ScheduledEventJobRepository scheduledEventJobRepository;
private final ScheduledBoardJobRepository scheduledBoardJobRepository;

@EventListener
public void handleEventScheduled(ScheduledEventJob scheduledEventJob) {
Expand All @@ -45,4 +49,27 @@ public void handleEventScheduled(ScheduledEventJob scheduledEventJob) {
}
}

@EventListener
public void handleBoardScheduled(ScheduledBoardJob scheduledBoardJob) {
JobDetail jobDetail = JobBuilder.newJob(BoardSchedulerConsumerV1Controller.class)
.withIdentity("boardJob-" + scheduledBoardJob.getJobId(), "boardGroup")
.usingJobData("boardId", scheduledBoardJob.getBoardId())
.build();
log.info("Job 등둝 μ™„λ£Œ. boardId: {}", scheduledBoardJob.getBoardId());

Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("boardTrigger-" + scheduledBoardJob.getJobId(), "boardGroup")
.startAt(Timestamp.valueOf(scheduledBoardJob.getScheduledTime()))
.build();
log.info("boardId {}에 λŒ€ν•œ Trigger 등둝 μ™„λ£Œ.", scheduledBoardJob.getBoardId());
log.info("Trigger μ‹œμž‘ μ‹œκ°„: {}", trigger.getStartTime());

try {
scheduler.scheduleJob(jobDetail, trigger);
scheduledBoardJobRepository.save(scheduledBoardJob);
} catch (SchedulerException e) {
throw new CommonException(ErrorCode.SCHEDULER_ERROR);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import com.daon.onjung.event.domain.redis.ScheduledEventJob;
import com.daon.onjung.event.repository.redis.ScheduledEventJobRepository;
import com.daon.onjung.event.application.controller.consumer.EventSchedulerConsumerV1Controller;
import com.daon.onjung.suggestion.application.controller.consumer.BoardSchedulerConsumerV1Controller;
import com.daon.onjung.suggestion.domain.redis.ScheduledBoardJob;
import com.daon.onjung.suggestion.repository.redis.ScheduledBoardJobRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
Expand All @@ -20,36 +23,59 @@ public class SchedulerRecoveryListener implements CommandLineRunner {

private final ScheduledEventJobRepository scheduledEventJobRepository;
private final Scheduler scheduler;
private final ScheduledBoardJobRepository scheduledBoardJobRepository;

@Override
public void run(String... args) throws Exception {
LocalDateTime now = LocalDateTime.now();
List<ScheduledEventJob> pendingJobs = scheduledEventJobRepository.findAll();
log.info("미처리 Job 쑰회 μ™„λ£Œ. 쑰회된 Job 수: {}", pendingJobs.size());
if (pendingJobs.isEmpty()) {
List<ScheduledEventJob> pendingEventJobs = scheduledEventJobRepository.findAll();
log.info("미처리 Event Job 쑰회 μ™„λ£Œ. 쑰회된 Job 수: {}", pendingEventJobs.size());
if (!pendingEventJobs.isEmpty()) {
for (ScheduledEventJob job : pendingEventJobs) {
if (job == null) {
log.warn("쑰회된 Job 쀑 null 객체가 μ‘΄μž¬ν•©λ‹ˆλ‹€.");
continue;
}
if (job.getScheduledTime() == null) {
log.warn("Job의 scheduledTime 값이 nullμž…λ‹ˆλ‹€. eventId: {}", job.getEventId());
continue;
}
if (job.getScheduledTime().isAfter(now)) {
log.info("미래 μž‘μ—… μŠ€μΌ€μ€„λŸ¬μ— μž¬λ“±λ‘. eventId: {}", job.getEventId());
scheduleEventJob(job);
} else {
executeEventJobImmediately(job);
}
}
}

List<ScheduledBoardJob> pendingBoardJobs = scheduledBoardJobRepository.findAll();
log.info("미처리 Board Job 쑰회 μ™„λ£Œ. 쑰회된 Job 수: {}", pendingBoardJobs.size());

if (pendingBoardJobs.isEmpty()) {
return;
}
for (ScheduledEventJob job : pendingJobs) {
for (ScheduledBoardJob job : pendingBoardJobs) {
if (job == null) {
log.warn("쑰회된 Job 쀑 null 객체가 μ‘΄μž¬ν•©λ‹ˆλ‹€.");
continue;
}
if (job.getScheduledTime() == null) {
log.warn("Job의 scheduledTime 값이 nullμž…λ‹ˆλ‹€. eventId: {}", job.getEventId());
log.warn("Job의 scheduledTime 값이 nullμž…λ‹ˆλ‹€. boardId: {}", job.getBoardId());
continue;
}
if (job.getScheduledTime().isAfter(now)) {
log.info("미래 μž‘μ—… μŠ€μΌ€μ€„λŸ¬μ— μž¬λ“±λ‘. eventId: {}", job.getEventId());
scheduleJob(job);
log.info("미래 μž‘μ—… μŠ€μΌ€μ€„λŸ¬μ— μž¬λ“±λ‘. boardId: {}", job.getBoardId());
scheduleBoardJob(job);
} else {
executeJobImmediately(job);
executeBoardJobImmediately(job);
}
}
}

private void scheduleJob(ScheduledEventJob job) throws SchedulerException {
private void scheduleEventJob(ScheduledEventJob job) throws SchedulerException {
JobDetail jobDetail = JobBuilder.newJob(EventSchedulerConsumerV1Controller.class)
.withIdentity("eventJob-" + job.getEventId(), "eventGroup")
.withIdentity("eventJob-" + job.getJobId(), "eventGroup")
.usingJobData("eventId", job.getEventId())
.build();

Expand All @@ -61,7 +87,7 @@ private void scheduleJob(ScheduledEventJob job) throws SchedulerException {
scheduler.scheduleJob(jobDetail, trigger);
}

private void executeJobImmediately(ScheduledEventJob scheduledEventJob) {
private void executeEventJobImmediately(ScheduledEventJob scheduledEventJob) {
try {
JobDetail jobDetail = JobBuilder.newJob(EventSchedulerConsumerV1Controller.class)
.withIdentity("eventJob-" + scheduledEventJob.getJobId(), "eventGroup")
Expand All @@ -86,4 +112,44 @@ private void executeJobImmediately(ScheduledEventJob scheduledEventJob) {
// μ‹€νŒ¨ μ‹œ μ‚­μ œν•˜μ§€ μ•ŠμŒ. ν•„μš”ν•˜λ©΄ μž¬μ‹œλ„ 큐에 μΆ”κ°€ν•˜λŠ” 둜직 κ³ λ €
}
}

private void scheduleBoardJob(ScheduledBoardJob job) throws SchedulerException {
JobDetail jobDetail = JobBuilder.newJob(BoardSchedulerConsumerV1Controller.class)
.withIdentity("boardJob-" + job.getJobId(), "boardGroup")
.usingJobData("boardId", job.getBoardId())
.build();

Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger-" + job.getJobId(), "boardGroup")
.startAt(Timestamp.valueOf(job.getScheduledTime()))
.build();

scheduler.scheduleJob(jobDetail, trigger);
}

private void executeBoardJobImmediately(ScheduledBoardJob scheduledBoardJob) {
try {
JobDetail jobDetail = JobBuilder.newJob(BoardSchedulerConsumerV1Controller.class)
.withIdentity("boardJob-" + scheduledBoardJob.getJobId(), "boardGroup")
.usingJobData("boardId", scheduledBoardJob.getBoardId())
.build();
log.info("Job 등둝 μ™„λ£Œ. boardId: {}", scheduledBoardJob.getBoardId());

Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("boardTrigger-" + scheduledBoardJob.getJobId(), "boardGroup")
.startNow()
.build();

// μž‘μ—… μŠ€μΌ€μ€„λ§
scheduler.scheduleJob(jobDetail, trigger);

// μ‹€ν–‰ 성곡 μ‹œ μž‘μ—… μ‚­μ œ
scheduledBoardJobRepository.delete(scheduledBoardJob);

log.info("이전에 λ“±λ‘ν–ˆμ§€λ§Œ μ‹€ν–‰μ•ˆλœ, 기간이 μ§€λ‚œ Job을 μ¦‰μ‹œ 싀행함. boardId: {}", scheduledBoardJob.getBoardId());
} catch (SchedulerException e) {
log.error("Job μ¦‰μ‹œμ‹€ν–‰μ— μ‹€νŒ¨. boardId: {}", scheduledBoardJob.getBoardId(), e);
// μ‹€νŒ¨ μ‹œ μ‚­μ œν•˜μ§€ μ•ŠμŒ. ν•„μš”ν•˜λ©΄ μž¬μ‹œλ„ 큐에 μΆ”κ°€ν•˜λŠ” 둜직 κ³ λ €
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.daon.onjung.event.application.controller.consumer;

import com.daon.onjung.event.repository.redis.ScheduledEventJobRepository;
import com.daon.onjung.event.application.usecase.ProcessCompletedEventUseCase;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -13,18 +12,12 @@
public class EventSchedulerConsumerV1Controller implements Job {

private final ProcessCompletedEventUseCase processCompletedEventUseCase;
private final ScheduledEventJobRepository scheduledEventJobRepository;

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// JobDataMap을 톡해 eventIdλ₯Ό κ°€μ Έμ˜¨λ‹€.
Long eventId = context.getJobDetail().getJobDataMap().getLong("eventId");

// eventIdλ₯Ό 톡해 ScheduledEventJob을 μ‚­μ œ
scheduledEventJobRepository.findByEventId(eventId)
.ifPresent(scheduledEventJobRepository::delete);
log.info("ScheduledEventJob μ‚­μ œ μ™„λ£Œ. eventId: {}", eventId);

processCompletedEventUseCase.execute(eventId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.daon.onjung.account.domain.User;
import com.daon.onjung.account.domain.type.EBankName;
import com.daon.onjung.account.repository.mysql.UserRepository;
import com.daon.onjung.event.domain.service.ScheduledEventJobService;
import com.daon.onjung.core.dto.CreateVirtualAccountResponseDto;
import com.daon.onjung.core.exception.error.ErrorCode;
import com.daon.onjung.core.exception.type.CommonException;
Expand All @@ -16,9 +15,11 @@
import com.daon.onjung.event.domain.mysql.Event;
import com.daon.onjung.event.domain.mysql.Ticket;
import com.daon.onjung.event.domain.service.EventService;
import com.daon.onjung.event.domain.service.ScheduledEventJobService;
import com.daon.onjung.event.domain.service.TicketService;
import com.daon.onjung.event.repository.mysql.EventRepository;
import com.daon.onjung.event.repository.mysql.TicketRepository;
import com.daon.onjung.event.repository.redis.ScheduledEventJobRepository;
import com.daon.onjung.onjung.repository.mysql.DonationRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -40,6 +41,7 @@ public class ProcessCompletedEventService implements ProcessCompletedEventUseCas
private final UserRepository userRepository;
private final TicketRepository ticketRepository;
private final DonationRepository donationRepository;
private final ScheduledEventJobRepository scheduledEventJobRepository;

private final EventService eventService;
private final TicketService ticketService;
Expand All @@ -55,6 +57,11 @@ public class ProcessCompletedEventService implements ProcessCompletedEventUseCas
@Transactional
public void execute(Long eventId) {

// eventIdλ₯Ό 톡해 ScheduledEventJob을 μ‚­μ œ
scheduledEventJobRepository.findByEventId(eventId)
.ifPresent(scheduledEventJobRepository::delete);
log.info("ScheduledEventJob μ‚­μ œ μ™„λ£Œ. eventId: {}", eventId);

// 이벀트 쑰회
Event currentEvent = eventRepository.findById(eventId)
.orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_RESOURCE));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.daon.onjung.suggestion.application.controller.consumer;

import com.daon.onjung.suggestion.application.usecase.ProcessCompletedBoardUseCase;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;

@RequiredArgsConstructor
@Slf4j
public class BoardSchedulerConsumerV1Controller implements Job {

private final ProcessCompletedBoardUseCase processCompletedBoardUseCase;

@Override
public void execute(JobExecutionContext context) {
// JobDataMap을 톡해 boardIdλ₯Ό κ°€μ Έμ˜¨λ‹€.
Long boardId = context.getJobDetail().getJobDataMap().getLong("boardId");

processCompletedBoardUseCase.execute(boardId);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import com.daon.onjung.core.exception.type.CommonException;
import com.daon.onjung.suggestion.application.dto.request.CommentMessage;
import com.daon.onjung.suggestion.application.dto.response.CreateCommentResponseDto;
import com.daon.onjung.suggestion.domain.Board;
import com.daon.onjung.suggestion.domain.Comment;
import com.daon.onjung.suggestion.domain.mysql.Board;
import com.daon.onjung.suggestion.domain.mysql.Comment;
import com.daon.onjung.suggestion.domain.service.BoardService;
import com.daon.onjung.suggestion.domain.service.CommentService;
import com.daon.onjung.suggestion.repository.mysql.BoardRepository;
Expand All @@ -21,7 +21,7 @@

@Service
@RequiredArgsConstructor
public class CommentV1Consumer {
public class CommentConsumerV1Controller {

private final BoardRepository boardRepository;
private final CommentRepository commentRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
import com.daon.onjung.core.exception.error.ErrorCode;
import com.daon.onjung.core.exception.type.CommonException;
import com.daon.onjung.suggestion.application.dto.request.LikeMessage;
import com.daon.onjung.suggestion.application.dto.response.CreateOrDeleteLikeResponseDto;
import com.daon.onjung.suggestion.domain.Board;
import com.daon.onjung.suggestion.domain.Like;
import com.daon.onjung.suggestion.domain.mysql.Board;
import com.daon.onjung.suggestion.domain.mysql.Like;
import com.daon.onjung.suggestion.domain.service.BoardService;
import com.daon.onjung.suggestion.domain.service.LikeService;
import com.daon.onjung.suggestion.repository.mysql.BoardRepository;
Expand All @@ -20,7 +19,7 @@

@Service
@RequiredArgsConstructor
public class LikeV1Consumer {
public class LikeConsumerV1Controller {

private final LikeRepository likeRepository;
private final BoardRepository boardRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.daon.onjung.account.domain.User;
import com.daon.onjung.core.dto.SelfValidating;
import com.daon.onjung.core.utility.DateTimeUtil;
import com.daon.onjung.suggestion.domain.Comment;
import com.daon.onjung.suggestion.domain.mysql.Comment;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Getter;
Expand Down
Loading